<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Pesimmoq</title>
    <description>The latest articles on DEV Community by Pesimmoq (@persimmoq).</description>
    <link>https://dev.to/persimmoq</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4185628%2F5303ed89-af3f-472d-8aa0-10436bb6f3d6.png</url>
      <title>DEV Community: Pesimmoq</title>
      <link>https://dev.to/persimmoq</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/persimmoq"/>
    <language>en</language>
    <item>
      <title>I built an AI coworker that works while I sleep, using nothing but Claude Code</title>
      <dc:creator>Pesimmoq</dc:creator>
      <pubDate>Fri, 16 Oct 2026 03:06:05 +0000</pubDate>
      <link>https://dev.to/persimmoq/i-built-an-ai-coworker-that-works-while-i-sleep-using-nothing-but-claude-code-6k8</link>
      <guid>https://dev.to/persimmoq/i-built-an-ai-coworker-that-works-while-i-sleep-using-nothing-but-claude-code-6k8</guid>
      <description>&lt;p&gt;Claude Code has a feature called &lt;strong&gt;routines&lt;/strong&gt;: a cloud session that starts on a cron schedule, clones a GitHub repository, uses the MCP connectors you've attached on claude.ai (Slack, Gmail), and exits. No server, no extra tooling.&lt;/p&gt;

&lt;p&gt;I used it to build a watcher that, every morning at 09:00 JST, reads 12 pages of Anthropic's official docs, diffs them against yesterday, posts a Japanese summary to Slack, and, when a change affects my books, pushes a draft article to GitHub. The motivation was embarrassing: I write guides about the Claude API, and I missed the Haiku 5.5 launch for &lt;strong&gt;five days&lt;/strong&gt;. A local script had been posting "changed" notices to Slack every day. Nobody was reading them.&lt;/p&gt;

&lt;p&gt;Everything below is as of October 16, 2026. Routines are moving fast; check the official docs for the current shape.&lt;/p&gt;

&lt;h2&gt;
  
  
  What a routine is
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;A 5-field cron expression (UTC) or a one-time timestamp starts a cloud session. &lt;strong&gt;Minimum interval is one hour.&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;The session starts with your GitHub repository cloned. It cannot see your local files, local environment variables, or local services.&lt;/li&gt;
&lt;li&gt;It can use MCP connectors attached on claude.ai (Slack, Gmail, ...). MCP servers configured only in Claude Code are not available.&lt;/li&gt;
&lt;li&gt;Model, allowed tools, and the prompt go in one JSON object. The prompt is read from scratch every run, so it has to be self-contained.&lt;/li&gt;
&lt;li&gt;Create, update, run-now, and run logs are available through an API (from inside Claude Code, the &lt;code&gt;RemoteTrigger&lt;/code&gt; tool). Deleting is web-only.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What I built
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;volvox-ltd/claude-docs-watch (private)
├── pages.json        # 12 official pages (the .md versions on platform.claude.com)
├── watch.py          # fetch -&amp;gt; compare with state/ -&amp;gt; diffs/&amp;lt;date&amp;gt;/ + result.json (stdlib only)
├── state/            # yesterday's text
├── diffs/            # unified diffs per day
├── drafts/           # article drafts the routine writes when a change matters
├── log/              # daily summaries
└── ROUTINE_PROMPT.md # the instructions the routine receives
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The design decision that matters: &lt;strong&gt;Python finds the diff; the model only judges and writes.&lt;/strong&gt; Asking a model to "read these 12 pages and tell me what changed" means reading ~300k characters every morning and missing things. &lt;code&gt;watch.py&lt;/code&gt; produces the diff files; the model reads only those.&lt;/p&gt;

&lt;h2&gt;
  
  
  The routine definition
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"claude-docs-watch 09:00 JST"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"cron_expression"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"0 0 * * *"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"enabled"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"job_config"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;"ccr"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"environment_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"env_…"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"session_context"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"model"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"claude-sonnet-5-5"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"sources"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[{&lt;/span&gt;&lt;span class="nl"&gt;"git_repository"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;"url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://github.com/volvox-ltd/claude-docs-watch"&lt;/span&gt;&lt;span class="p"&gt;}}],&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"allowed_tools"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"Bash"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Read"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Write"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Edit"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Glob"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Grep"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                        &lt;/span&gt;&lt;span class="s2"&gt;"mcp__Slack__slack_send_message"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"mcp__Slack__slack_search_channels"&lt;/span&gt;&lt;span class="p"&gt;]},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"events"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[{&lt;/span&gt;&lt;span class="nl"&gt;"data"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;"uuid"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"…"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"session_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"user"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"parent_tool_use_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="nl"&gt;"message"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;"role"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"user"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"content"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&amp;lt;the prompt below&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;}}}]}},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"mcp_connections"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[{&lt;/span&gt;&lt;span class="nl"&gt;"connector_uuid"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"…"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Slack"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://mcp.slack.com/mcp"&lt;/span&gt;&lt;span class="p"&gt;}]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Sonnet 5.5 is plenty: the daily job is "read a diff and summarize it".&lt;/p&gt;

&lt;h2&gt;
  
  
  The prompt
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;The repository https://github.com/volvox-ltd/claude-docs-watch is already cloned in your
working directory (branch main). Configure git with user.name 'docs-watch-bot' and
user.email 'contact@volvox-ltd.com' before committing.

You are the daily docs watcher for persimmoq, an author of Claude API guides. You run
inside a fresh clone of this repository every morning. Work in Japanese for all
human-facing text.

Do these steps in order.

1. Run `git pull --rebase origin main` first (the checkout can be stale). Then run
   `python3 watch.py` from the repository root and read `result.json`.

2. If `changed` is empty and `errors` is empty: append one line `&amp;lt;date&amp;gt; no changes` to
   `log/&amp;lt;YYYY-MM&amp;gt;.md`, commit it, push to `main`, and send ONE short Slack message to the
   private channel #mail (channel_id C0BEY8JUCDR). Then stop.

3. If there are changes: read every file listed under `changed[].diff`. Ignore pure
   formatting changes. For the substantive changes, write a summary with, per page: the
   page key, 1–3 sentences on what changed, and a judgement on whether it affects the
   author's published material (the books on Claude 5 migration and on Managed Agents,
   and the articles on those topics). Mark each page as affected / not affected / check.

4. Write that summary to `log/&amp;lt;YYYY-MM&amp;gt;.md` under a heading `## &amp;lt;date&amp;gt;` and post the same
   summary to the Slack channel. Keep it under 2,000 characters; link each page URL.

5. If at least one page is affected and the change is a new model, a new price, a new
   breaking change, a deprecation/retirement, or a new Managed Agents feature: write ONE
   draft article in `drafts/&amp;lt;date&amp;gt;-&amp;lt;short-slug&amp;gt;.md` (front matter with published: false),
   quoting the exact new text from the diff where it matters, linking the official page,
   and ending with a section "What I verified" containing only a placeholder for the author
   to fill in after testing against the live API. Do not invent behavior that the
   documentation does not state. Do not claim anything was tested.

6. `git add -A`, commit, push to `main`. If the push fails, retry once after `git pull --rebase`.

7. If any `errors` are present, mention them at the end of the Slack message.

Never publish anything outside this repository. Never edit files under `state/` by hand.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Step 5 is the point. &lt;strong&gt;The coworker drafts; it never publishes.&lt;/strong&gt; The draft ends with an empty "What I verified" section that a human fills in after running the real API. The prompt says "do not claim anything was tested" for the same reason.&lt;/p&gt;

&lt;h2&gt;
  
  
  What happened on the first two runs (October 16)
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Run 1 (23 seconds, 8 turns).&lt;/strong&gt; Sandbox allocated, repo cloned, &lt;code&gt;watch.py&lt;/code&gt; found no changes, log appended, push succeeded, Slack post failed with &lt;code&gt;channel_not_found&lt;/code&gt;. The agent searched for the channel, found nothing, and fell back to a mobile push notification. Cause: the Slack connector on claude.ai was attached to a different workspace. I reconnected it and put the channel ID in the prompt.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Run 2 (51 seconds, 9 turns).&lt;/strong&gt; Slack post succeeded. Then the push was rejected: the sandbox's checkout predated run 1's commit. The agent ran &lt;code&gt;git pull --rebase&lt;/code&gt;, saw its own commit was a duplicate line, discarded it, and exited cleanly. Reasonable, but I added &lt;code&gt;git pull --rebase&lt;/code&gt; as step 1 so it doesn't happen every morning.&lt;/p&gt;

&lt;p&gt;The run log is available from the API with timestamps for every tool call, error, and the final message. You can read everything the coworker did while you were asleep.&lt;/p&gt;

&lt;h2&gt;
  
  
  Three things that broke
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;The GitHub App must be installed on the organization.&lt;/strong&gt; Connecting GitHub on claude.ai was not enough for a private repo under an org; creating the routine failed with &lt;code&gt;repo_access_denied&lt;/code&gt; until I installed github.com/apps/claude on the org and granted the repo.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A connector points at one workspace.&lt;/strong&gt; With several Slack workspaces, it was attached to the wrong one. Use channel IDs, not names.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The checkout is not always fresh.&lt;/strong&gt; A routine that pushes should pull first.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Cost and limits
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Runs use the allowance of my Claude subscription plan; I have seen no separate API charges. A no-change run is a few thousand tokens. Check the pricing page for your plan.&lt;/li&gt;
&lt;li&gt;Minimum interval one hour. Not a tool for "poll every five minutes".&lt;/li&gt;
&lt;li&gt;No access to your local machine. Anything the job needs must be in the repo or reachable from the cloud.&lt;/li&gt;
&lt;li&gt;Deletion is web-only.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Three ways to build the same thing
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;Claude Code routine&lt;/th&gt;
&lt;th&gt;Managed Agents&lt;/th&gt;
&lt;th&gt;cron + API on your machine&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Runs on&lt;/td&gt;
&lt;td&gt;Anthropic's cloud&lt;/td&gt;
&lt;td&gt;Anthropic's cloud&lt;/td&gt;
&lt;td&gt;your machine&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Setup&lt;/td&gt;
&lt;td&gt;one JSON&lt;/td&gt;
&lt;td&gt;Agent + Deployment&lt;/td&gt;
&lt;td&gt;plist/crontab + script&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Billing&lt;/td&gt;
&lt;td&gt;plan allowance&lt;/td&gt;
&lt;td&gt;tokens + session time ($0.08/h)&lt;/td&gt;
&lt;td&gt;API tokens&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Best for&lt;/td&gt;
&lt;td&gt;periodic jobs that fit in a repo + connectors&lt;/td&gt;
&lt;td&gt;long-running agents that need a hosted toolbox&lt;/td&gt;
&lt;td&gt;jobs that need local files or local credentials&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Notify via&lt;/td&gt;
&lt;td&gt;connectors (Slack/Gmail), push&lt;/td&gt;
&lt;td&gt;webhooks&lt;/td&gt;
&lt;td&gt;your own&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;I use all three. This watcher is a routine; my production agent platform is Managed Agents; the weekly Search Console report, which needs local OAuth tokens, stays on launchd.&lt;/p&gt;

&lt;h2&gt;
  
  
  Takeaways
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;A Claude Code routine gives you a cron'd cloud agent with a repo and Slack, with no infrastructure.&lt;/li&gt;
&lt;li&gt;Split the roles: Python detects, the model judges and writes, a human publishes.&lt;/li&gt;
&lt;li&gt;What breaks is permissions and connections, not the prompt.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The 400-errors-when-migrating guide this watcher protects is here: &lt;a href="https://persimmoq.gumroad.com/l/claude-5-migration-guide" rel="noopener noreferrer"&gt;Claude 5 Migration Guide&lt;/a&gt; (PDF, $19).&lt;/p&gt;

</description>
      <category>claude</category>
      <category>anthropic</category>
      <category>ai</category>
      <category>automation</category>
    </item>
    <item>
      <title>Claude Opus 5.5 / Sonnet 5.5: 5 settings that return 400 when you only change the model name</title>
      <dc:creator>Pesimmoq</dc:creator>
      <pubDate>Thu, 15 Oct 2026 01:47:16 +0000</pubDate>
      <link>https://dev.to/persimmoq/claude-opus-55-sonnet-55-5-settings-that-return-400-when-you-only-change-the-model-name-5g36</link>
      <guid>https://dev.to/persimmoq/claude-opus-55-sonnet-55-5-settings-that-return-400-when-you-only-change-the-model-name-5g36</guid>
      <description>&lt;p&gt;Claude Opus 5.5 shipped on September 22, 2026 and Claude Sonnet 5.5 on September 28. If you take code that runs on Opus 5 or Sonnet 5 and change only the &lt;code&gt;model&lt;/code&gt; string, one of these five settings will return an HTTP 400. All five are in Anthropic's official migration guides; I reproduced the first one against the live API on October 6 and pasted the exact responses below.&lt;/p&gt;

&lt;p&gt;A static scanner that finds these in your code (file:line) is open source: &lt;a href="https://github.com/volvox-ltd/claude5-migration-kit" rel="noopener noreferrer"&gt;claude5-migration-kit&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python scan.py path/to/your/app &lt;span class="nt"&gt;--target&lt;/span&gt; opus-5-5
python scan.py path/to/your/app &lt;span class="nt"&gt;--target&lt;/span&gt; sonnet-5-5
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  1. &lt;code&gt;thinking: {"type": "disabled"}&lt;/code&gt; returns 400
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Opus 5.5 cannot turn thinking off.&lt;/strong&gt; On Opus 5 you could send &lt;code&gt;disabled&lt;/code&gt; at &lt;code&gt;high&lt;/code&gt; effort or below. On Opus 5.5, both &lt;code&gt;disabled&lt;/code&gt; and &lt;code&gt;enabled&lt;/code&gt; + &lt;code&gt;budget_tokens&lt;/code&gt; are rejected at every effort level:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"thinking.type.disabled" is not supported for this model. Use "thinking.type.adaptive" and "output_config.effort" to control thinking behavior.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Omit &lt;code&gt;thinking&lt;/code&gt; (same as adaptive) and lower &lt;code&gt;output_config.effort&lt;/code&gt; where you used to disable thinking.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Sonnet 5.5 replaces &lt;code&gt;disabled&lt;/code&gt; with &lt;code&gt;between_tools&lt;/code&gt;.&lt;/strong&gt; It is the lowest thinking setting: no up-front thinking, only the short notes between tool calls.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;To turn thinking off on this model, send "thinking": {"type": "between_tools"} instead of {"type": "disabled"}. The model does not think before responding. The short updates it writes between tool calls come back as thinking blocks.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Sonnet 5
&lt;/span&gt;&lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;claude-sonnet-5&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;max_tokens&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;16000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                       &lt;span class="n"&gt;thinking&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;type&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;disabled&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="n"&gt;output_config&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;effort&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;xhigh&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="n"&gt;messages&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[...])&lt;/span&gt;

&lt;span class="c1"&gt;# Sonnet 5.5
&lt;/span&gt;&lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;claude-sonnet-5-5&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;max_tokens&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;16000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                       &lt;span class="n"&gt;thinking&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;type&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;between_tools&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="n"&gt;output_config&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;effort&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;high&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="n"&gt;messages&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[...])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;between_tools&lt;/code&gt; works only at &lt;code&gt;high&lt;/code&gt; effort or below (400 with &lt;code&gt;xhigh&lt;/code&gt; / &lt;code&gt;max&lt;/code&gt;), takes no other field (&lt;code&gt;display&lt;/code&gt;, &lt;code&gt;budget_tokens&lt;/code&gt; and &lt;code&gt;block_binding&lt;/code&gt; are 400), and cannot be combined with per-message effort changes. In a request without tools it answers without thinking at all, so move multi-step reasoning tasks back to adaptive.&lt;/p&gt;

&lt;p&gt;Both responses above are verbatim from the API (&lt;code&gt;max_tokens: 64&lt;/code&gt;, no charge for a 400).&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Forced &lt;code&gt;tool_choice&lt;/code&gt; returns 400
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;{"type": "any"}&lt;/code&gt; and &lt;code&gt;{"type": "tool", "name": ...}&lt;/code&gt; are rejected on both models, including on the token-counting endpoint:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;tool_choice: type "tool" and "any" are not supported for this model.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Use &lt;code&gt;tool_choice: {"type": "auto"}&lt;/code&gt;, mark the tool &lt;code&gt;strict: true&lt;/code&gt; so the input matches the schema, and say in the prompt when to call it. Strict tools are capped at 20 per request and need &lt;code&gt;additionalProperties: false&lt;/code&gt; on every object. If you only wanted JSON, use structured outputs (&lt;code&gt;output_config.format&lt;/code&gt;) instead of a tool. &lt;strong&gt;On Amazon Bedrock, Opus 5.5 and Sonnet 5.5 have no structured outputs (strict included)&lt;/strong&gt;: send &lt;code&gt;auto&lt;/code&gt;, name the tool in the prompt, and validate the input yourself.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. &lt;code&gt;computer_20251124&lt;/code&gt; returns 400 on the Claude API and Google Cloud
&lt;/h2&gt;

&lt;p&gt;Declare computer use as the &lt;code&gt;computer_toolset_20260801&lt;/code&gt; toolset (no beta header). Sonnet 5.5 also rejects &lt;code&gt;computer_20250124&lt;/code&gt; on every platform. Amazon Bedrock keeps &lt;code&gt;computer_20251124&lt;/code&gt;. The &lt;code&gt;fine-grained-tool-streaming-2025-05-14&lt;/code&gt; header is a 400 next to a toolset entry; set &lt;code&gt;eager_input_streaming: true&lt;/code&gt; on the tools that need it.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Editing conversation history returns 400 (or drops the thinking)
&lt;/h2&gt;

&lt;p&gt;The preserved-thinking check that Fable 5.1 introduced now applies to both models: thinking blocks are bound to the model and to the conversation prefix. Editing &lt;code&gt;system&lt;/code&gt;, &lt;code&gt;tools&lt;/code&gt; or earlier turns and then sending the thinking blocks back is a 400 on accounts created on or after August 31, 2026 (enforced by default), or a dropped block otherwise.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Keep history append-only. Change instructions with a mid-conversation &lt;code&gt;{"role": "system", ...}&lt;/code&gt; message.&lt;/li&gt;
&lt;li&gt;Change tools with &lt;code&gt;tool_addition&lt;/code&gt; / &lt;code&gt;tool_removal&lt;/code&gt;; with the &lt;code&gt;inline-tools-2026-09-15&lt;/code&gt; beta you can include full definitions.&lt;/li&gt;
&lt;li&gt;To shrink history, use on-demand compaction (&lt;code&gt;compact-2026-09-04&lt;/code&gt;): you receive a signed summary block and send it first on the next request.&lt;/li&gt;
&lt;li&gt;Sonnet 5.5 thinking blocks are also &lt;strong&gt;account-bound&lt;/strong&gt;: sent from another organization they are silently dropped.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  5. Sonnet 5.5 rejects Opus 4.x / Sonnet 5 as advisors
&lt;/h2&gt;

&lt;p&gt;With a Sonnet 5.5 executor, the advisor must be Opus 5, Opus 5.5, Sonnet 5.5, Fable 5 / 5.1 or Mythos 5 / 5.1. Opus 4.8 / 4.7 / 4.6, Sonnet 5, Sonnet 4.6 and Haiku 5.5 return 400. Advice comes back encrypted as &lt;code&gt;advisor_redacted_result&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Changes that don't fail, but matter
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Opus 5.5 defaults to &lt;code&gt;effort: medium&lt;/code&gt;&lt;/strong&gt; (Opus 5: &lt;code&gt;high&lt;/code&gt;). Carry over a request without &lt;code&gt;effort&lt;/code&gt; and it runs one level lower. Anthropic reports that 5.5 at &lt;code&gt;medium&lt;/code&gt; matches or beats Opus 5 at &lt;code&gt;high&lt;/code&gt;; start there and sweep.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sonnet 5.5 effort levels are recalibrated.&lt;/strong&gt; Start coding agents at &lt;code&gt;medium&lt;/code&gt;, general work at &lt;code&gt;high&lt;/code&gt;, &lt;code&gt;max_tokens&lt;/code&gt; 128K with streaming.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Text between tool calls now arrives in &lt;code&gt;thinking&lt;/code&gt; blocks&lt;/strong&gt;, empty at the default &lt;code&gt;display&lt;/code&gt;. A UI that streams progress notes goes quiet with no error. Use &lt;code&gt;display: "updates"&lt;/code&gt; (beta header &lt;code&gt;thinking-display-updates-2026-08-18&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;More refusal categories.&lt;/strong&gt; Opus 5.5 adds &lt;code&gt;bio&lt;/code&gt;; Sonnet 5.5 has &lt;code&gt;cyber&lt;/code&gt;, &lt;code&gt;bio&lt;/code&gt;, &lt;code&gt;frontier_llm&lt;/code&gt;, &lt;code&gt;reasoning_extraction&lt;/code&gt;, &lt;code&gt;general_harms&lt;/code&gt;. Server-side fallback only retries &lt;code&gt;cyber&lt;/code&gt; and &lt;code&gt;frontier_llm&lt;/code&gt; on Sonnet 5. Since September 24, refusals before any output in &lt;code&gt;bio&lt;/code&gt; / &lt;code&gt;frontier_llm&lt;/code&gt; / &lt;code&gt;reasoning_extraction&lt;/code&gt; are billed.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Prompt cache minimum is 512 tokens&lt;/strong&gt; (Sonnet 5: 1,024). Sonnet 5.5 cache reads dropped to $0.10/MTok on October 7 (0.05x).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Priority Tier is not supported on Opus 5.5.&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sonnet 4.5 retires on November 30, 2026.&lt;/strong&gt; Replacement: Sonnet 5.5.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;#&lt;/th&gt;
&lt;th&gt;Symptom&lt;/th&gt;
&lt;th&gt;Fix&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;disabled&lt;/code&gt; → 400&lt;/td&gt;
&lt;td&gt;Opus 5.5: omit + lower effort. Sonnet 5.5: &lt;code&gt;between_tools&lt;/code&gt; (≤ &lt;code&gt;high&lt;/code&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;tool_choice: any&lt;/code&gt; → 400&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;auto&lt;/code&gt; + &lt;code&gt;strict&lt;/code&gt; + name the tool in the prompt&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;computer_20251124&lt;/code&gt; → 400&lt;/td&gt;
&lt;td&gt;&lt;code&gt;computer_toolset_20260801&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;edited history → 400&lt;/td&gt;
&lt;td&gt;append-only; system messages, tool_addition, compaction&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;advisor → 400&lt;/td&gt;
&lt;td&gt;Opus 5 / 5.5, Sonnet 5.5, Fable&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The seven things that already broke when moving from 4.x to Opus 5 / Sonnet 5 (&lt;code&gt;temperature&lt;/code&gt;, &lt;code&gt;budget_tokens&lt;/code&gt;, prefill, &lt;code&gt;max_tokens&lt;/code&gt; eaten by thinking, &lt;code&gt;content[0]&lt;/code&gt; on refusals, empty thinking text, the ~30% tokenizer increase) still apply.&lt;/p&gt;

&lt;p&gt;The full guide, with per-model checklists, the prompt re-tuning table across 4.7 → 4.8 → Opus 5 → Fable 5.1 → 5.5, prompt caching and history design, and verification scripts, is a 70-page PDF: &lt;a href="https://persimmoq.gumroad.com/l/claude-5-migration-guide" rel="noopener noreferrer"&gt;Claude 5 Migration Guide&lt;/a&gt; ($19). Written with AI assistance; every API behavior was checked against the live API or the official docs before publication.&lt;/p&gt;

&lt;p&gt;Official sources: &lt;a href="https://platform.claude.com/docs/en/models/opus-5-5/migration-guide" rel="noopener noreferrer"&gt;Opus 5.5 migration guide&lt;/a&gt; · &lt;a href="https://platform.claude.com/docs/en/models/sonnet-5-5/migration-guide" rel="noopener noreferrer"&gt;Sonnet 5.5 migration guide&lt;/a&gt;&lt;/p&gt;

</description>
      <category>claude</category>
      <category>anthropic</category>
      <category>llm</category>
      <category>api</category>
    </item>
  </channel>
</rss>
