Sweep 22 Sep 2026 · 17:19Z Build v2.1.280 501 read Stable v2.1.267 Latest v2.1.280 Next v2.1.280 Feeds RSS JSON llms.txt Unofficial
One change · api

preserved-thinking changed

build-with-claude/preserved-thinking

Nearest release: v2.1.273, published under an hour after this site recorded the change. Shown because the two are within 24 hours of each other. Nothing here says the release caused the edit.

Recorded here
Lines+59added
Lines−36removed
From line 384 where the diff opens
First seen 1 Sep 2026 this site's first read of the page
Recorded edits10to this page, all time

#### Background (async) compaction

The whole hunk

from line 384, old and new numbered
/
lines
from line 384
384384 
385385Each row compares two consecutive requests:
386386 
387| Change between requests | Later thinking blocks |
388| -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------- |
389| Append messages at the end | Valid |
390| Add a tool with `defer_loading: true` that nothing has referenced yet | Valid |
391| Remove `thinking` blocks from the start of the history, from the end, or all of them | Valid (the model loses that reasoning) |
392| Change any request parameter outside `system`, `tools`, and `messages` (`effort`, `max_tokens`, `output_config`, `tool_choice`, `metadata`, `thinking.display`, and so on) | Valid |
393| Add, move, or remove `cache_control` markers | Valid |
394| A rotating signed URL that returns the same bytes | Valid |
395| Server-side compaction or context editing removes or replaces content | Valid (the check compares what you sent, not the server's edited copy) |
396| A cleared [turn-scoped system message](https://platform.claude.com/docs/en/build-with-claude/preserved-thinking#per-turn-reminders) left in place | Valid |
397| Edit, reorder, or delete any earlier `user`, `assistant`, or `system` message | Invalid |
398| Re-render the context you put in the first user message with a changed value | Invalid for every thinking block |
399| Clear or shorten an earlier `tool_result`, re-encode an earlier image, or change an earlier `tool_use` input | Invalid for every later thinking block |
400| Add a text block to an earlier user turn, or remove one you added last time | Invalid |
401| Change the top-level `system` string or blocks | Invalid |
402| Add, remove, rename, or edit a tool in `tools` | Invalid |
403| Remove a `thinking` block from the middle of the history and keep later ones | Invalid for every later thinking block |
404| Put back a `thinking` block you removed on an earlier request | Invalid for thinking blocks produced while it was gone |
405| An image or document URL that returns different bytes on the next request | Invalid |
406| The same turn-scoped message deleted or reworded on a later request | Invalid |
387| Change between requests | Later thinking blocks |
388| -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
389| Append messages at the end | Valid |
390| Add a tool with `defer_loading: true` that nothing has referenced yet | Valid |
391| Remove `thinking` blocks from the start of the history, from the end, or all of them | Valid (the model loses that reasoning) |
392| Change any request parameter outside `system`, `tools`, and `messages` (`effort`, `max_tokens`, `output_config`, `tool_choice`, `metadata`, `thinking.display`, and so on) | Valid |
393| Add, move, or remove `cache_control` markers | Valid |
394| A rotating signed URL that returns the same bytes | Valid |
395| Server-side compaction or context editing removes or replaces content | Valid (the check compares what you sent, not the server's edited copy) |
396| A cleared [turn-scoped system message](https://platform.claude.com/docs/en/build-with-claude/preserved-thinking#per-turn-reminders) left in place | Valid |
397| Edit, reorder, or delete any earlier `user`, `assistant`, or `system` message | Invalid, except when the signed block from [on-demand compaction](https://platform.claude.com/docs/en/build-with-claude/preserved-thinking#server-side-trimming) replaces the messages it summarizes, under the conditions in [Keep-tail compaction](https://platform.claude.com/docs/en/build-with-claude/preserved-thinking#keep-tail-compaction) |
398| Re-render the context you put in the first user message with a changed value | Invalid for every thinking block |
399| Clear or shorten an earlier `tool_result`, re-encode an earlier image, or change an earlier `tool_use` input | Invalid for every later thinking block |
400| Add a text block to an earlier user turn, or remove one you added last time | Invalid |
401| Change the top-level `system` string or blocks | Invalid |
402| Add, remove, rename, or edit a tool in `tools` | Invalid |
403| Remove a `thinking` block from the middle of the history and keep later ones | Invalid for every later thinking block |
404| Put back a `thinking` block you removed on an earlier request | Invalid for thinking blocks produced while it was gone |
405| An image or document URL that returns different bytes on the next request | Invalid |
406| The same turn-scoped message deleted or reworded on a later request | Invalid |
407407 
408408### Check whether your code edits the prefix
409409 
from line 786
786786 
787787Each common prefix edit has a replacement that gives the model the same information and leaves earlier bytes unchanged, so later thinking stays valid. Find the edit your code makes today in the first column:
788788 
789| Instead of | Use | Beta header |
790| --------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------- |
791| Rebuilding the top-level `system` prompt | A [mid-conversation system message](https://platform.claude.com/docs/en/build-with-claude/preserved-thinking#new-instructions) | None |
792| Re-rendering the context in your first user message (environment, date, memory, project instructions) on each request | Render it once and resend it unchanged. When something changes, [put the new version in the newest turn](https://platform.claude.com/docs/en/build-with-claude/preserved-thinking#changing-context) | None |
793| Clearing or shortening old `tool_result` content, or re-encoding old images, in place | Shorten a tool result or downscale an image before the first time you send it, not after. To clear old results later, [trim context on the server](https://platform.claude.com/docs/en/build-with-claude/preserved-thinking#server-side-trimming) with `clear_tool_uses_20250919` | `context-management-2025-06-27` |
794| Injecting a reminder and deleting it on the next request | A [turn-scoped system message](https://platform.claude.com/docs/en/build-with-claude/preserved-thinking#per-turn-reminders) (`clear_at: "next_user_message"`) | `mid-conversation-system-clear-at-2026-08-21` |
795| Adding or removing entries in `tools` | [`tool_addition` and `tool_removal` blocks](https://platform.claude.com/docs/en/build-with-claude/preserved-thinking#tool-changes) | `mid-conversation-tool-changes-2026-07-01` |
796| Changing top-level `output_config.effort` (restarts the cache, doesn't affect thinking) | A [per-message `output_config`](https://platform.claude.com/docs/en/build-with-claude/preserved-thinking#effort-changes) | `mid-conversation-output-config-2026-07-01` |
797| Dropping or summarizing old turns on the client | Server-side [compaction or context editing](https://platform.claude.com/docs/en/build-with-claude/preserved-thinking#server-side-trimming), or [client-side compaction](https://platform.claude.com/docs/en/build-with-claude/preserved-thinking#custom-compaction-on-the-client) that keeps no stale thinking | `compact-2026-01-12` or `context-management-2025-06-27` |
798| An image or document URL whose bytes change between requests | A [`file_id` from the Files API](https://platform.claude.com/docs/en/build-with-claude/preserved-thinking#files-by-id), or base64 | None |
789| Instead of | Use | Beta header |
790| --------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------ |
791| Rebuilding the top-level `system` prompt | A [mid-conversation system message](https://platform.claude.com/docs/en/build-with-claude/preserved-thinking#new-instructions) | None |
792| Re-rendering the context in your first user message (environment, date, memory, project instructions) on each request | Render it once and resend it unchanged. When something changes, [put the new version in the newest turn](https://platform.claude.com/docs/en/build-with-claude/preserved-thinking#changing-context) | None |
793| Clearing or shortening old `tool_result` content, or re-encoding old images, in place | Shorten a tool result or downscale an image before the first time you send it, not after. To clear old results later, [trim context on the server](https://platform.claude.com/docs/en/build-with-claude/preserved-thinking#server-side-trimming) with `clear_tool_uses_20250919` | `context-management-2025-06-27` |
794| Injecting a reminder and deleting it on the next request | A [turn-scoped system message](https://platform.claude.com/docs/en/build-with-claude/preserved-thinking#per-turn-reminders) (`clear_at: "next_user_message"`) | `mid-conversation-system-clear-at-2026-08-21` |
795| Adding or removing entries in `tools` | [`tool_addition` and `tool_removal` blocks](https://platform.claude.com/docs/en/build-with-claude/preserved-thinking#tool-changes) | `mid-conversation-tool-changes-2026-07-01` |
796| Changing top-level `output_config.effort` (restarts the cache, doesn't affect thinking) | A [per-message `output_config`](https://platform.claude.com/docs/en/build-with-claude/preserved-thinking#effort-changes) | `mid-conversation-output-config-2026-07-01` |
797| Dropping or summarizing old turns on the client | [On-demand compaction](https://platform.claude.com/docs/en/build-with-claude/preserved-thinking#server-side-trimming) to keep the recent turns with their thinking, other server-side [compaction or context editing](https://platform.claude.com/docs/en/build-with-claude/preserved-thinking#server-side-trimming), or [client-side compaction](https://platform.claude.com/docs/en/build-with-claude/preserved-thinking#custom-compaction-on-the-client) that keeps no stale thinking | `compact-2026-09-04` (not on Amazon Bedrock or Google Cloud) |
798| An image or document URL whose bytes change between requests | A [`file_id` from the Files API](https://platform.claude.com/docs/en/build-with-claude/preserved-thinking#files-by-id), or base64 | None |
799799 
800800All of these assume you [send assistant turns back exactly as returned](https://platform.claude.com/docs/en/build-with-claude/preserved-thinking#append-assistant-turns-exactly-as-returned). Mid-conversation system messages, turn-scoped system messages, and tool changes aren't available on every model: [Mid-conversation system messages and tool changes](https://platform.claude.com/docs/en/build-with-claude/mid-conversation-system-messages) lists the models that accept them. If your code serves several models, keep editing the top-level `system` prompt for the models that don't accept them.
801801 
802To use several betas in one request, combine the values in one `anthropic-beta` header. The same names apply on Amazon Bedrock and Google Cloud (see [Beta headers](https://platform.claude.com/docs/en/api/beta-headers)):
802To use several betas in one request, combine the values in one `anthropic-beta` header. Beta names are the same on Amazon Bedrock and Google Cloud wherever the beta is available there (see [Beta headers](https://platform.claude.com/docs/en/api/beta-headers)):
803803 
804804```text wrap
805805anthropic-beta: thinking-binding-controls-2026-08-01,mid-conversation-system-clear-at-2026-08-21,mid-conversation-tool-changes-2026-07-01
from line 941
941941 
942942Another common prefix edit is client-side trimming: dropping or summarizing the oldest turns and keeping the recent ones verbatim. The kept turns' thinking blocks were produced while the removed history was still in place, so they fail the check. The server-side equivalents don't count as edits, because the check compares the conversation as you sent it:
943943 
944* [Compaction](https://platform.claude.com/docs/en/build-with-claude/compaction) summarizes older turns into a compaction block when the context approaches a threshold you set, and the checked prefix restarts from that block. Its [`instructions` parameter](https://platform.claude.com/docs/en/build-with-claude/compaction#custom-summarization-instructions) takes your own summarization prompt, such as "preserve every ticker, position size, and stated assumption".
944* [Compaction](https://platform.claude.com/docs/en/build-with-claude/compaction) summarizes older turns into a compaction block when the context approaches a threshold you set, and the checked prefix restarts from that block. Its [`instructions` parameter](https://platform.claude.com/docs/en/build-with-claude/compaction#custom-summarization-instructions) takes your own summarization prompt, such as "preserve every ticker, position size, and stated assumption". [On-demand compaction](https://platform.claude.com/docs/en/build-with-claude/preserved-thinking#background-compaction) (beta) returns the summary from a separate request, which can [run in the background](https://platform.claude.com/docs/en/build-with-claude/preserved-thinking#background-compaction). Send `"compaction": {"type": "summarize"}` in the request body, and the response carries a single `compaction` block, holding the summary and a signature, instead of a reply. On-demand compaction is available on the Claude API but not on Amazon Bedrock or Google Cloud, and it needs the `compact-2026-09-04` beta header on the summary request and on every later request that carries the block. You send the block in place of the messages it summarizes. The check accepts that swap, so the turns you keep can stay valid with their thinking, under the conditions in [Keep-tail compaction](https://platform.claude.com/docs/en/build-with-claude/preserved-thinking#keep-tail-compaction).
945945* [Context editing](https://platform.claude.com/docs/en/build-with-claude/context-editing) clears old tool results or old thinking blocks by rule, oldest first. The strategies are `clear_tool_uses_20250919` and `clear_thinking_20251015`.
946946 
947947### Compact on the client
948948 
949You can still compact on the client. Once you rewrite anything earlier in the conversation, don't send back a thinking block that was produced before the rewrite.
949You can still compact on the client. If you write the summary yourself, don't send back a thinking block that was produced before the rewrite. If the API writes it with on-demand compaction, [Keep-tail compaction](https://platform.claude.com/docs/en/build-with-claude/preserved-thinking#keep-tail-compaction) lists when kept thinking stays valid.
950950 
951951#### Simple compaction (recommended)
952952 
from line 967
967967 
968968#### Keep-tail compaction
969969 
970Keep-tail compaction summarizes the older turns and keeps the most recent turns verbatim, so the model still sees the last few exchanges word for word. As usually written it breaks the rule: the kept assistant turns still carry thinking blocks that were produced when the original turns, not the summary, came before them. Those blocks fail.
970Keep-tail compaction summarizes the older turns and keeps the most recent turns verbatim, so the model still sees the last few exchanges word for word. If you write the summary yourself, it breaks the rule: the kept assistant turns still carry thinking blocks that were produced when the original turns, not the summary, came before them. Those blocks fail.
971971 
972To keep that thinking, have the API write the summary with [on-demand compaction](https://platform.claude.com/docs/en/build-with-claude/preserved-thinking#server-side-trimming). Send only the older turns in a request with the `compaction` parameter and the `compact-2026-09-04` beta header. Then send the signed block it returns in place of those turns, followed by the kept turns exactly as returned. The kept thinking stays valid while all of these hold:
973 
974* The compaction request runs on a model with preserved thinking. The conversation's own model is the simple choice.
975* The kept turns directly follow the summarized messages, and the first kept message isn't one the API would merge into the last summarized one: a message with the same role, or a `role: "system"` message.
976* `system` and your non-deferred `tools` match the compaction request.
977 
978The simplest way to meet the second is to compact exactly the `messages` of a request you already made. Mid-conversation system messages inside the summarized turns are summarized too, so their instructions and tool changes stop applying after the swap. To keep one in force, state it again in a `role: "system"` message directly after the first new `user` turn that follows the kept turns. A system message placed between the block and the kept turns breaks their thinking.
979 
980The rest of this section covers a summary you write yourself.
981 
972982![Keep-tail compaction: the history is replaced by a summary of turns 1 and 2 followed by turns 3 to 5 verbatim; the thinking on assistant turns 3 and 4 was produced after the original turns, not the summary, so it fails; the same request sent with prefix\_mismatch\_behavior drop\_block succeeds, the API drops those two blocks and lists them in input\_transformations](https://platform.claude.com/docs/images/preserved-thinking-keep-tail-compaction.svg)
973983 
974984Fix: keep the turns exactly as they are and send `prefix_mismatch_behavior: "drop_block"`. The API drops the stale thinking blocks, the model reads the kept turns' `text` and `tool_use` blocks, and the request succeeds.
from line 1194
11841194 
11851195Keep sending `"drop_block"` on later requests for as long as those two turns stay in the history. Thinking the model produces from this request onward follows the summary and stays valid. If you'd rather not depend on the beta header, the alternative is to strip the `thinking` and `redacted_thinking` blocks from the kept assistant turns yourself when you build the compacted history.
11861196 
1197#### Background (async) compaction
1198 
1199Background compaction builds the summary off the critical path while the conversation continues, then swaps it in a few requests later. Have the API write the summary with [on-demand compaction](https://platform.claude.com/docs/en/build-with-claude/preserved-thinking#server-side-trimming):
1200 
12011. Send the conversation so far in a separate request with the `compaction` parameter and the `compact-2026-09-04` beta header.
12022. Keep working on the full history while that request runs.
12033. On the first request after the block arrives, send it in place of the messages the compaction request held, followed by every turn appended since.
1204 
1205The thinking produced while the summary was being built stays valid under the same conditions as in [Keep-tail compaction](https://platform.claude.com/docs/en/build-with-claude/preserved-thinking#keep-tail-compaction).
1206 
1207A summary you build yourself breaks the rule the same way keep-tail does, with a delay: every assistant turn produced while the summary was being built carries thinking that predates the swap, and it all fails the moment the summary lands. If you use one, treat the swap like keep-tail and send `"drop_block"` from the swap onward, or compact synchronously.
1208 
11871209#### Patterns that don't work with preserved thinking
11881210 
1189* **Background compaction.** Building the summary off the critical path and swapping it in a few requests later breaks the rule the same way keep-tail does, with a delay: every assistant turn produced while the summary was being built carries thinking that predates the swap, and it all fails the moment the summary lands. If you need it, treat the swap like keep-tail and send `"drop_block"` from the swap onward. Otherwise compact synchronously.
11901211* **Cutting turns out of the middle.** Removing individual turns invalidates every thinking block after them, and no compaction scheme avoids that. If you were cutting a turn to change an instruction, append a [mid-conversation system message](https://platform.claude.com/docs/en/build-with-claude/preserved-thinking#new-instructions) instead. To remove old tool results or old thinking selectively, use server-side [context editing](https://platform.claude.com/docs/en/build-with-claude/context-editing).
11911212* **Compacting in the middle of a tool round.** Don't compact between an assistant turn's `tool_use` and the `tool_result` that answers it. Send that assistant turn back with its thinking intact so the model finishes the round with its reasoning. See [Preserving thinking blocks](https://platform.claude.com/docs/en/build-with-claude/thinking#preserving-thinking-blocks).
11921213 
from line 1244
12231244 </Accordion>
12241245 
12251246 <Accordion title="I compact by summarizing older turns and keeping recent turns verbatim. Does that still work?">
1226 Not if the kept turns still carry their thinking: those blocks were produced against the history you replaced, so they fail the check. Strip `thinking` and `redacted_thinking` blocks from the turns you carry across and keep their `text` and `tool_use` blocks, or send `prefix_mismatch_behavior: "drop_block"` and let the API drop them. Simple compaction leaves no thinking behind to fail and is the recommended approach: one summary message plus the next user turn, with no earlier turns replayed. Server-side [compaction](https://platform.claude.com/docs/en/build-with-claude/compaction) and [context editing](https://platform.claude.com/docs/en/build-with-claude/context-editing) don't count as edits. See [Compact on the client](https://platform.claude.com/docs/en/build-with-claude/preserved-thinking#custom-compaction-on-the-client).
1247 Yes, if the API writes the summary. [On-demand compaction](https://platform.claude.com/docs/en/build-with-claude/preserved-thinking#server-side-trimming) (beta header `compact-2026-09-04`) summarizes the older turns into a signed block that you send in place of them. The recent turns keep their thinking under the conditions in [Keep-tail compaction](https://platform.claude.com/docs/en/build-with-claude/preserved-thinking#keep-tail-compaction).
1248 
1249 If you write the summary yourself, the kept turns' thinking fails the check, because those blocks were produced against the history you replaced. Strip `thinking` and `redacted_thinking` blocks from the turns you carry across and keep their `text` and `tool_use` blocks, or send `prefix_mismatch_behavior: "drop_block"` and let the API drop them. Simple compaction leaves no thinking behind to fail and is the recommended approach: one summary message plus the next user turn, with no earlier turns replayed. Server-side [compaction](https://platform.claude.com/docs/en/build-with-claude/compaction) and [context editing](https://platform.claude.com/docs/en/build-with-claude/context-editing) don't count as edits. See [Compact on the client](https://platform.claude.com/docs/en/build-with-claude/preserved-thinking#custom-compaction-on-the-client).
12271250 </Accordion>
12281251 
12291252 <Accordion title="How do I handle instruction files such as AGENTS.md or CLAUDE.md that change mid-session?">