---
title: "Claude Fable 5.2 API Session Replay and Rollback Tests"
canonical: https://wavect.io/blog/claude-fable-5-2-session-replay/
language: en
description: "Test whether Claude Fable 5.2 can resume saved agent sessions. Run six offline storage checks, then verify tool results and rollback on the live Messages API."
image: "https://wavect.io/img/blog/headers/header_claude-fable-5-2-session-replay.png"
author: ["Kevin Riedl"]
published: "2026-11-14"
updated: "2026-11-14"
reviewed: "2026-11-14"
---

# Can Claude Fable 5.2 resume your saved agent sessions?

[**Back**](/blog/overview/)

[![Kevin Riedl](/img/team/kevin.webp)](/team/kevin-riedl/)

[Kevin Riedl](/team/kevin-riedl/) https://linkedin.com/in/wsdt

10 min read · 14 Nov 2026 Last reviewed November 14, 2026

[**Next**](/blog/coding-with-claude-fable-5/)

TL;DR

To resume a Claude Fable 5.2 session, restore the previous request configuration, ordered messages, full assistant turn and matching tool results. Run the six-case Python fixture through your own storage. Then verify the invoice amount, tool count and cost on a live upgrade and rollback. Fable 5.1 can accept a request while losing access to 5.2 thinking.

An invoice agent looks up `DEMO-17`. The accounting system returns EUR 47.50. Before the agent can tell the user, a deployment restarts the worker. Your database contains the chat, and your dashboard shows a successful lookup. Can the next worker finish the answer without asking for the invoice again?

For an application using the Claude Messages API, the answer depends on what went into the database. A transcript that looks complete to a person can lose an entire assistant turn when that turn contained a tool call and no visible text. A release can also change an old conversation by loading today's system prompt. Both bugs can survive a demo that always starts a fresh chat.

**Research checked 14 November 2026.** We ran the six local storage checks below against synthetic records. The model behavior comes from Anthropic's documentation. The live upgrade and rollback cases are a test plan for your deployment. If you use the coding CLI, the [Fable 5.2 guide for Claude Code](/blog/coding-with-claude-fable-5/) covers its model settings.

## What changes on the first request after a restart?

The first resumed request combines the state your application saved with the configuration your new worker loads. On the synchronous Claude API, Fable 5.2 can reject a preserved thinking block with HTTP 400 when an earlier part of the conversation has changed. The first turn of a brand-new chat never exercises that check on an old block. [Anthropic's Fable 5.2 migration guide](https://platform.claude.com/docs/en/models/fable-5-2/migration-guide)

Take an innocuous release. Yesterday the tool description said “Read one recorded invoice total.” Today it adds “and currency.” Both versions could return exactly the same data. If the worker reconstructs yesterday's conversation using the new tool definition, the input preceding the saved block has changed. Retrying that request three times sends the same mismatch three times.

The prefix check compares parsed values. Whitespace between JSON tokens and the order of keys in an object can change. The order of items in an array matters, as do the contents of prior messages and tool definitions. A changed `max_tokens` or `effort` alone does not explain this particular error. An edit can invalidate blocks produced after the edit. Older blocks that precede it have a different history. Message Batches also have a different default when mismatch behavior is unset. [What the API includes in a prefix check](https://platform.claude.com/docs/en/build-with-claude/preserved-thinking/prefix-checks)

## What should the worker save before it stops?

Save what you would need to construct the next API request, even when the UI has nothing to display. Keep the effective system instructions and ordered tools from the last successful request, the ordered message history, the full assistant content array, and any tool result your application has already obtained. [Anthropic's advice for saving and resuming a conversation](https://platform.claude.com/docs/en/build-with-claude/preserved-thinking/change-tools-or-instructions)

| What was saved | What the next worker can establish |
| --- | --- |
| Original request inputs | The caller requested DEMO-17 with a particular system instruction and tool definition. A deployment can resolve those versions or restore their stored values. |
| Assistant turn | An opaque thinking block with an empty visible summary and a lookup with ID `toolu_demo_17` arrived in this order. A text-only export would lose both. |
| Result and receipt | The application recorded EUR 47.50 for that call. It can supply the recorded result and check the next answer against an independent value. |
| Operational state | The lookup completed, but delivery of the final answer is pending. A replacement worker knows which step remains. |

The model's thinking block is opaque to your application. Preserve the returned fields as part of the assistant turn. There is no need to extract reasoning or print it in a log. For a client tool, the next user message supplies a `tool_result` for the matching `tool_use.id`. Put results first in that message, with no intervening chat turn. Parallel calls each need their own matching result. [Claude API rules for returning tool results](https://platform.claude.com/docs/en/agents-and-tools/tool-use/handle-tool-calls)

## How can you test your own session storage offline?

Run the [downloadable Python replay checker](/downloads/claude-fable-5-2-session-replay/check_replay.py) before changing your model setting. It uses the Python 3 standard library and needs no API key. The invoice, tool ID and signature field are synthetic. The package tests the data that your application saves and loads. Its placeholder signature only has meaning inside this fixture.

```
python3 check_replay.py
python3 check_replay.py --emit-fixture > original.json
# Save original.json through your application, restart the worker,
# then export the loaded record to restored.json.
python3 check_replay.py --check-restored restored.json
```

The default run reported `6/6 expected outcomes`. One intact record passed and each of five damaged records produced its expected failure label. The five negative controls make a difference in practice. A checker that approves every session will fail its own test. Feeding `original.json` straight back to the checker only tests the reference file. For a release decision, cross the same database, queue, SDK conversion and reload boundaries that a customer session crosses.

| Change applied | Observed classification | Where to look in an application |
| --- | --- | --- |
| None; no assistant text | `intact` | A renderer that filters out empty chat bubbles must still save this turn. |
| System instruction edited | `changed prefix: system` | The worker might be resolving a mutable prompt alias. |
| Tool description edited | `changed prefix: tools` | A schema generator might be pulling the deployed version into old sessions. |
| Earlier request rewritten | `changed prefix: messages` | A summarizer might be saving its display copy over the original turn. |
| Assistant blocks reversed | `changed assistant turn` | Rows returned without an explicit ordinal can reassemble in a different order. |
| Wrong result ID | `unmatched tool result` | A correlation bug can attach a valid invoice total to another call. |

The checker normalizes JSON object keys and preserves array order. It compares the archived values and checks call/result linkage. Its equality rule is deliberately strict for application storage. It cannot authenticate an Anthropic signature, reproduce provider errors or tell you whether a model can use a block. Extend the fixture with your own shapes, especially parallel calls with out-of-order completion, and a restart between a tool returning and its receipt being saved.

## What happens when a session moves from 5.1 to 5.2 and back?

On the direct Claude API, Fable 5.2 can read preserved thinking from Fable 5.1 when the earlier inputs remain valid. Fable 5.1 cannot read blocks produced by 5.2. Rolling a session back can therefore return HTTP 200 while the older model continues without some earlier reasoning. Your application can still hold the full original history. A provider-side omission on one request does not rewrite the database. [How preserved thinking works across model switches](https://platform.claude.com/docs/en/build-with-claude/preserved-thinking)

Separate the decision to reroute new traffic from the decision to move an active session. For new invoice requests you can switch the model at session creation. For work already in progress, record the model on the session and let that cohort finish on its existing route where available. A model change partway through should be an explicit, observable event. Our [model routing guide](/blog/claude-model-router-hooks-vs-proxy/) explains where such a decision can be made.

If an old thread already fails the prefix check, compare your restored system, tools and earlier turns with the last known successful request. Recover an intact version when possible. If the original is gone, start a new session from verified business facts. For DEMO-17, that means the invoice reference, the recorded EUR 47.50, its receipt and the fact that an answer is outstanding. Keep that handoff visible as a new session. [Anthropic's troubleshooting guide for a bound thinking block](https://platform.claude.com/docs/en/build-with-claude/preserved-thinking/fix-bound-to-a-different-conversation)

## Which live checks should gate the rollout?

Use a non-production account with the same provider route, SDK and persistence adapter as the release. Obtain genuine blocks from that account for each test. Give the read-only tool a controlled invoice and record every invocation. Judge the final answer against the independently stored amount and currency. The proposed cases below have distinct failure signals.

| Run | What to do | Evidence to keep |
| --- | --- | --- |
| Fresh 5.2 baseline | Complete one lookup without a restart using `claude-fable-5-2`. | Model ID, request IDs, tool count, EUR 47.50 in the final answer, usage and elapsed time. |
| Same-model restart | Stop after recording the result, reload on a fresh worker and continue on 5.2. | The answer matches the receipt and the invocation count stays at one. Record any extra read as a separate outcome. |
| 5.1 to 5.2 | Obtain a genuine 5.1 tool turn, persist it and continue on 5.2 with its original prefix. | Capture status, returned model and accepted business result. If it fails, diff the stored fields against the outgoing request. |
| 5.2 to 5.1 | Repeat the switch in reverse using genuine 5.2 history. | Capture the result, added calls, tokens and latency. A correct answer alone cannot establish that earlier thinking was readable. |
| Deliberately edited prefix | Use a disposable copy of a genuine 5.2 turn on the synchronous direct API. Change only its earlier system instruction, keeping the affected block. | Observe the default prefix error and the worker's recovery path. Record the field and request ID without logging the conversation. |

An illustrative release gate for this workflow is one correct amount and currency, one lookup and no writes per accepted case. Any wrong invoice or duplicate external action calls for investigation before expansion. Set latency and cost thresholds against your existing service target. Keep fresh and resumed traffic in separate groups. Thousands of successful new conversations can otherwise hide every broken restart. See the [release QA checklist](/software-development-guide/software-qa-checklist-before-launch/) for the wider sign-off.

In a workflow that can issue a refund, a timeout after submission is an accounting question. Check the downstream system using a stable operation ID for that logical refund. Repeat only if the provider confirms that the first submission can no longer commit, or use its documented idempotent retry contract with the same operation ID.

Saving the Claude tool ID helps correlate messages. Duplicate prevention also needs the system that performs the refund to recognize repeated attempts. [AWS on idempotent API retries](https://aws.amazon.com/builders-library/making-retries-safe-with-idempotent-APIs/) · [A worked example of recovering an uncertain send](/blog/agentmail-saas-duplicate-sends-recovery/)

## When do retries erase Fable 5.2's token savings?

At standard direct API prices, 25,000 fresh input tokens and 2,000 output tokens cost $0.35 on Fable 5.1 and $0.28 on 5.2. The listed rates per million tokens are $10/$50 and $8/$40 respectively for input/output. This example assumes identical usage on every attempt. Cache, batch, tools, infrastructure and human-review charges are excluded. [Fable 5.2 specifications and prices](https://platform.claude.com/docs/en/models/fable-5-2/overview) · [Fable 5.1 specifications and prices](https://platform.claude.com/docs/en/models/fable-5-1/overview)

Suppose 20 accepted invoice answers take 20 attempts on 5.1. The model bill is $7.00. If restarts and retries make the same 20 accepted answers take 25 attempts on 5.2, the bill is also $7.00. A 26th attempt brings it to $7.28, or $0.364 per accepted answer. These are worked figures. In a pilot, divide actual costs for all attempts by the count of independently accepted results. Keep failed tasks in the cost numerator.

A team choosing whether to migrate can now inspect three pieces of evidence together. Did the stored turn survive a restart? Did a real model complete the right task once? What did that accepted result cost? If your team needs a repeatable release suite for its own workflows, our [AI evaluation and LLMOps service](/services/ai-evaluation-llmops/) covers that work. [Discuss an evaluation for your agent](/contact/?intent=ai-evaluation-llmops).

The [Twinsoft AI case study](/case-studies/twinsoft-ai/) shows how a prototype was prepared for an enterprise pilot. Use it for the wider product-release decision.

## Fable 5.2 session replay FAQ

### Can I use a screenshot or a chat export to reconstruct a session?

A display export usually contains only the text a person saw. Check whether it preserves the complete assistant content array, earlier system and tool definitions, ordered messages and result IDs. If it omits any of them, use its verified facts to start a new session and identify that handoff explicitly.

### Does a 400 always mean the thinking prefix changed?

Read the error detail and record the request ID. Malformed messages and result blocks that point to the wrong call can also fail validation. Compare the saved and outgoing structures one field at a time. Repeating the same malformed request adds a retry without repairing the input.

### Should we send the signature from the download to Claude?

Use the download locally. Its signature is a conspicuous synthetic sentinel that lets the checker detect changes. A live acceptance case needs an assistant turn returned by the provider on your test route and account. Keep any real signed blocks inside the approved persistence boundary.

### How should a worker handle an assistant response with no text?

Inspect the stop reason and all content blocks. A tool call can be waiting for its result even when there is nothing to display. A token-limited response can also end before any text is emitted. Persist the returned turn and handle its actual stop condition before marking the job complete.

### Should we put customer conversations in regression tests?

Start with synthetic invoices and reproducible tool outputs. They allow another engineer to run the same failure cases without customer records. When a production incident reveals a new shape, construct the smallest artificial example that reproduces the storage defect and add that shape to the suite.

### Will the offline result predict behavior on Bedrock or in Message Batches?

The local checker measures your stored data. Run a separate acceptance case for each provider surface and processing mode you deploy. The live matrix here assumes synchronous calls on the direct Claude API. In particular, a batch item can drop mismatched blocks under its default behavior.

QA and production readiness

## Read next

Testing, audits, maintenance and hardening practices for reliable production software.

[Start here**QA for AI-Generated Code**](/blog/qa-for-ai-generated-code/)

- [A 2026 AI agent development stack, tested on a frontend regression](/blog/pi-agent-development-stack/)
- [Alibaba Open Code Review returned no comments. Which files did it check?](/blog/alibaba-open-code-review-no-comments/)
- [How can a water utility field-test a LoRaWAN meter reading and leak alarm?](/blog/lorawan-water-meter-field-acceptance-test/)
- [Both software vendors say they’re done. What should you test before signing off?](/blog/multi-vendor-software-acceptance-testing/)
- [README ZIP malware: review the actual AI tool install](/blog/readme-zip-malware-install-review/)

[Next article**A 2026 AI agent development stack, tested on a frontend regression**](/blog/pi-agent-development-stack/)

[**Back**](/blog/overview/)

[![Kevin Riedl](/img/team/kevin.webp)](/team/kevin-riedl/)

[Kevin Riedl](/team/kevin-riedl/) https://linkedin.com/in/wsdt

10 min read · 14 Nov 2026 Last reviewed November 14, 2026

[**Next**](/blog/coding-with-claude-fable-5/)
