PARAS MADAN
All writing

Latest in AI

OpenAI Agents JS 0.22: Avoid RunState Failures During a Rolling Upgrade

Some saved runs remain compatible with 0.21 workers, while richer checkpoints require a newer reader, making a simple resume test insufficient.

OpenAI Agents JS 0.22.0 can save runs using either schema 1.23 or 1.24. A mixed deployment with 0.21 workers can therefore resume one checkpoint and reject another. Before upgrading a service that pauses agents for approval, check which workers will read the saved state, not just which workers create it.

The 0.22.0 core changelog describes richer JSON usage metadata and conditional preservation of the older format. This guide is based on tagged source and checked-in tests, not a tested production migration.

Why two runs can produce different schema versions

The 0.22.0 serializer retains 1.23 when the state remains compatible. Richer metadata can require 1.24, as can newer nested runs, recovered-handoff evidence, child-owned approval state or version-6 sandbox envelopes. The schema decision covers more than the top-level token totals.

The compatibility tests make the distinction concrete. Numeric usage details, including nested numeric objects, retain 1.23 in the tested cases. String, boolean, null and array values select 1.24. Tests also show a newer child snapshot causing its parent and grandparent to select the newer schema without rewriting the child's saved bytes.

That creates a misleading smoke test: a basic run resumes successfully on an older worker, so the deployment appears compatible. A later run with richer usage details or a nested checkpoint takes a different path. Compatibility depends on the saved state, not merely on whether both deployments use the same agent name.

What an older worker does with schema 1.24

The 0.21.0 reader validates the schema version against its supported list and rejects unsupported versions. It does not silently accept a 1.24 checkpoint because most fields look familiar.

Do not change $schemaVersion to 1.23 or remove unfamiliar fields to make the error disappear. The newer format can preserve approval and execution information, not just optional reporting labels. A successful parse after manual editing would not establish that the resumed run still means the same thing.

A deployment plan for paused approvals

Consider a document-processing service that pauses an agent before sending a result to a customer. Worker A writes the checkpoint; hours later, worker B receives the approval and resumes it. A rolling deployment can put those workers on different SDK versions even though the user sees one continuous task.

My recommendation is to treat the checkpoint reader as a deployment dependency. Before allowing new workers to write checkpoints, establish that every worker eligible to resume those checkpoints can read them. If that cannot happen together, isolate the new version's work queue from older readers rather than letting any worker claim any paused run.

Record the writer package version and schema version alongside the checkpoint identifier. These are useful routing and diagnostic fields, but the SDK's own validation must remain authoritative. Avoid copying the complete saved state into routine logs, since it can contain conversation and tool data.

Test the boundaries before enabling new writers

Use staging copies or synthetic states without real external side effects. This is a proposed acceptance plan:

  • Resume an ordinary numeric-usage checkpoint with the intended reader versions.
  • Repeat with richer usage metadata and a nested run requiring the newer schema.
  • Exercise the approval and sandbox paths your application actually uses.
  • Confirm that an incompatible checkpoint is quarantined for a compatible reader, not repeatedly retried or manually rewritten.
  • Rehearse rollback while newer checkpoints still exist.

Rolling back application code does not roll back the state already written. Keep a compatible resume path available, or finish the affected runs before retiring it. Do not restart a workflow from its original input merely to avoid a schema error without first checking whether its earlier tools already changed anything.

The upgrade boundary is the queue of unfinished work. A deployment is only reversible if the workers left behind can safely finish what the newer workers started.

I'm Paras. I work at the intersection of AI, engineering and distribution.

I help developer-tool teams turn SDK changes and migration risks into technical guides people can use.

Book a 30-minute call.