Skip to content
OTFotf
All posts

How to resume a signed-in browser task safely across agent turns

D
DaveAuthor
7 min read
Byte works at a laptop beside a fading browser window and a separate durable task checkpoint while Dex explains, Luna takes notes, and Nova hovers nearby.

A signed-in browser can make an agent workflow feel continuous: it opens a dashboard, pauses for a person, then returns to the same page on a later turn. That continuity is useful, but temporary. The remote session can expire or crash while the application’s task is still unfinished.

Cloudflare’s Agents SDK now offers a browserTool backed by Browser Run. It can preserve tabs, cookies, and login state between turns while the browser session stays alive. The engineering question is how to use that convenience without treating a browser as durable task storage or permanent authorization. The Cloudflare announcement describes the lifecycle hook and the behavior when a browser restarts.

Separate the task from the browser

A browser session is an execution resource. Your application owns the task. Keep a durable record of what the user asked the agent to do, which safe step has completed, what needs human approval, and what evidence should be checked before continuing.

Do not use an open tab as the only record that work is in progress. Tabs and login cookies may survive a turn boundary, but the default idle timeout is ten minutes. If the browser expires or crashes, a later call gets a replacement browser, not a restored copy of the old one.

A useful task record might contain a task ID, account or workspace ID, current step, target site, checkpoint description, and a state such as ready, needs_user, needs_reauthentication, or complete. Keep credentials and session cookies in the browser or your approved secret store; do not copy them into an agent transcript or task log. Store enough state to decide what to do next, not a replayable transcript of every secret-bearing interaction.

This separation also makes cancellation and retries easier to reason about. If a worker wakes after hibernation, it can load the task record first, then decide whether the browser is still a usable continuation. If the browser is new, the task record still tells the application what the user intended and which steps were already confirmed. The record should describe business progress independently of the browser’s tabs.

Dex and Nova compare a sturdy task ledger with completed checkpoints and a next-step marker to a separate blank browser window on its own dock.

Keep task identity and confirmed progress in application-owned storage, separate from the remote browser session.

Register the browser with the agent lifecycle

The Cloudflare example creates a Browser with browserRun and registers it through Lifecycle.install(this).use(this.browser).use(this.harness). That lets the Durable Object reconnect to the browser session after it hibernates, provided the remote browser itself has not expired.

Use the SDK version and adapter that match your harness. The announcement specifies Agents SDK v0.28.0 or later for this browser tool. The exact wiring differs between Pi Durable, the AI SDK, and TanStack AI, so follow the example for the adapter your app actually runs. Avoid assuming that a tool interface from one harness has identical scope behavior in another.

For each conversation, define how a browser tab is selected. Pi gives each conversation its own active tab by default. The AI SDK and TanStack AI adapters share an active tab when no scope is supplied; pass a conversation identifier when you want separate active tabs. That is tab selection, not a security boundary: cookies and logins are shared inside one Browser. If two users need separate signed-in sessions, give them separate browser instances rather than relying on different tab scopes.

11 production screens. Login and database wired.

The SaaS Dashboard Kit includes login, a database, and a working dashboard. Live demo at saas.otf-kit.dev.

See the live demo

Treat restarted true as a recovery event

When a browser expires, closes, or crashes, the next use can report restarted: true. The previous tabs and login state are gone. That result should move your task into an explicit recovery path; it should not silently continue as if the old session were present.

A safe recovery sequence is:

  1. Load the application’s task record and identify the last step that was confirmed.
  2. Inspect the current browser state instead of assuming that a page or tab exists.
  3. If the task needs a signed-in site, ask the user to authenticate again through an approved flow.
  4. Recheck the account and page after authentication, then resume from a known checkpoint.
  5. Before a consequential action, verify that it has not already happened.

The last check matters for actions such as sending a message, submitting an order, changing account settings, or approving a payment. An interrupted browser call is not proof that the action failed. Cloudflare notes that Pi does not automatically replay a browser call interrupted by eviction because repeating it could submit a form or click a button twice. Persist an action state around consequential steps, and reconcile with the site before retrying.

Do not blindly replay the previous browser command after a restart. A command may have completed before the session died, or the replacement browser may be on an unrelated page. Make resumption depend on application state and verified page evidence. For a write, inspect the current server-side result or page state before deciding to retry.

Byte reauthenticates in a replacement browser while Nova inspects the account and page; a safety cover remains over a consequential action button.

After a browser restart, reauthenticate and verify the current state before resuming a consequential action.

Make reauthentication a product flow

A task that depends on a login needs a visible path for when the session is no longer valid. The user should know which account needs attention, why the agent paused, and how to resume without repeating completed work. Build a pause and resume path into your product so a person can restore authentication through your approved flow. Make clear which account needs attention, why the agent paused, and how to continue without repeating completed work; do not treat authentication as an invisible implementation detail.

Use the least access the task needs. Bind the task to the correct user or workspace, and prevent one person’s browser session from being reused for another person. Require a fresh authorization check for high-impact actions even when a page still appears signed in. A surviving cookie says that a session may still be active; it does not replace your app’s policy about what the agent may do.

Also decide how the task behaves when a user does not return. A pending browser task should expire according to your product’s own rules. Keep the task record long enough to explain the pause, but make reauthentication and any required approval explicit before execution continues. Offer a clear resume action after the user signs in again; do not make a person repeat the original request just because the browser was replaced.

Test the failure cases, not just the happy path

Before shipping, test the same task in several states: two turns within the browser’s idle window, a return after more than ten idle minutes, an explicit browser close, and a simulated interruption around a state-changing action. Confirm that normal continuation can use the expected tab, while a restart moves the task into recovery and does not repeat a consequential operation.

Test account separation with two users who have different logins. Changing a tab scope should not accidentally make cookies private; the documentation says they remain shared within the Browser. Check that each user gets the right browser instance and that the application records its own checkpoint independently of browser state.

Finally, make recovery observable. Log a task ID, the transition into reauthentication, whether the browser reported a restart, and the verified outcome of the next step. Avoid logging cookies, passwords, or full page contents that could contain personal information. This gives support staff enough context to investigate a stalled task without turning logs into another source of credentials.

Choose persistence as a bounded convenience

Persistent browser sessions reduce repeated setup when a user returns soon, and they can support a human handoff during a multi-turn task. They do not make a browser permanent. The default idle timeout is ten minutes, and a restart creates a fresh browser with no old tabs or login state.

Build the workflow around that boundary: persist intent and progress in your application, scope each browser to the right user, recognize restarted: true, and reauthenticate before continuing protected work. Then a session expiry becomes a recoverable interruption rather than lost task state or an unsafe replay.

For a separate event-driven workflow, see our guide to turning issue events into an agent investigation; it covers event handling, not persistent browser sessions.

If you need an editable starting point for a SaaS dashboard or internal research console, the OTF SaaS Dashboard kit provides a React and Postgres app shell. It is an optional UI starting point; it does not include a Cloudflare Agents SDK or Browser Run integration.

Sources

agentsarchitectureai-tools
OTF SaaS Dashboard Kit

Ship the product, not the setup.

  • 11 production screens — auth, team, analytics, and settings
  • Login and a real database are wired in
  • AI configs pre-tuned so your agent extends instead of regenerates
Need more than components?

Full-stack kits.
Pay once, own the code.

SaaS Dashboard and Fitness include authentication and a database. Arcade is browse-first with a local demo session and no backend sign-in by default. Booking is in Preview; Marketplace is coming soon and not currently sold. The Bundle includes the three live kits.

Everything Bundle — $149See full pricing

Get the free AI configs pack

AI configs in every kit: CLAUDE.md, .cursorrules and task prompts. Drop them in and your AI tool instantly understands your project.

No spam. Unsubscribe any time.

Prefer the free SDK? Star it on GitHub →