# Factory-built and database-stored components get crash-safe background runs

> Agno AgentOS now puts background runs for AgentFactory, TeamFactory, WorkflowFactory, components created through the components API and version-pinned runs on the durable queue, and the worker rebuilds each component from a scope saved on the ticket. Polling a factory run returns the run.

- Published: 2026-10-16
- Author: Yash Pratap Solanky
- Categories: Changelog
- Canonical: https://www.agno.com/blog/factory-built-and-database-stored-components-get-crash-safe-background-runs
- Markdown: https://www.agno.com/blog/factory-built-and-database-stored-components-get-crash-safe-background-runs.md

Agno's AgentOS stamps a resolution scope on the durable ticket for an `AgentFactory`, `TeamFactory` or `WorkflowFactory`, a component created through the components API, or a version-pinned run, and the queue worker replays that resolution when it claims the job. Earlier releases accepted these runs with a 202, logged that they bypass the durable queue and ran them as a detached task on the accepting replica, so a crash or deploy there lost them.

For a stored component the scope records where it came from, its owner and the version to execute, so a publish after submission leaves the queued run on the version it was accepted with. For a factory the ticket carries the `user_id`, `session_id`, validated `factory_input`, and the trusted claims and scopes the auth middleware set at the door. The worker calls the factory again with that context, and `/queue/jobs` shows the claims as `"[redacted]"`.

Polling a factory run works now too. Every run read route used to resolve the factory without a request and answer 400; reads go to the factory's run rows and never call the factory. We ran the same `AgentFactory` on both releases, with an embedded Postgres and a stub model standing in for a real one:

```text
Before
POST /agents/durable-writer/runs  202
WARNING Background run bypasses the durable queue ... NOT durable.
GET run: 400 {"detail": "Request context is required for factory agents"}

Now
POST /agents/durable-writer/runs  202
INFO    Agent queued: durable-writer
GET run: 200 {"status": "COMPLETED", "content": "done: Write about job queues."}
GET /queue/jobs/{run_id}: 200 {"pinned": null, "source": "factory", "context": {"input": {"style": "limerick"}, "claims": "[redacted]", "scopes": [], "user_id": "mira", ...}}
```

The worker has no HTTP request, so `ctx.request` there is a `QueuedRequest`. A factory that reads a header from it still gets its 202 at the door, then the run ends `ERROR` with the fix in its content:

```text
GET run: 200 {"status": "ERROR", "content": "Factory could not build the component: Factory read ctx.request.headers, but queued runs have no HTTP request. Pass what the factory needs through factory_input or the trusted claims."}
```

Build the component from the context's data fields only. The factory can run more than once for a single run, on any replica, so keep its output a function of the context.

See the [cookbook](https://github.com/agno-agi/agno/blob/main/cookbook/05_agent_os/21_factories/08_durable_queue.py), and learn more about [factories](https://docs.agno.com/agent-os/factories/overview) and the [durable queue](https://docs.agno.com/agent-os/background-execution/durable-queue) in the documentation.
