[Bug] Advisor "unavailable" = `advisorModel: fable` + any `tool_use` in the transcript; executor-irrelevant, `opus` advisor immune (supersedes #73923's ToolSearch cause)
Summary
The advisor tool's generic error_code: "unavailable" has a specific, deterministic trigger that I don't think any existing issue states:
**advisorModel: fable+ anytool_useblock in the transcript →unavailable.**
- The executor is irrelevant — reproduces with
opus,opus[1m], andsonnet. advisorModel: opusis immune — it succeeds after tool calls, same account, same prompt.- With
fable, the advisor works fine until the first tool call of any kind, then fails and stays latched off for the session (cf. #74530, #67411). - Tool identity doesn't matter:
Bash("echo hi")is enough. Not image-specific, notRead-specific. - Not ToolSearch. Reproduces with MCP fully disabled and
ENABLE_TOOL_SEARCH=false, withBashas the only tool in the transcript. (See "Relationship to #73923" below.) - Not context size. The failing transcripts are a few hundred tokens.
- Failures return in 4–8s; successes take 27–55s. This is a validation rejection, not a capacity/queue timeout.
Client-side logging shows the tool is attached and the pairing validates — [AdvisorTool] Server-side tool enabled with claude-fable-5 as the advisor model — so this is a server-side rejection of the request, not a local skip.
Environment
- Claude Code 2.1.205, macOS 26.5.1, arm64
- Subscription OAuth, first-party Anthropic API
advisorModel: "fable",model: "opus[1m]"(a documented-valid pairing)CLAUDE_CODE_DISABLE_ADVISOR_TOOLnot set
Results matrix
Identical prompt and flags throughout. --strict-mcp-config with an empty MCP config, so no MCP servers and no deferred-tool loading. "Prior tool use" = the model runs echo hi via Bash before calling the advisor.
| Executor | Advisor | Prior tool use | Result | Latency |
|---|---|---|---|---|
| opus | fable | none | ✅ received | 27s |
| opus[1m] | fable | none | ✅ received | 42s |
| opus | fable | none (2nd turn, --continue) | ✅ received | 27s |
| opus | fable | Bash | ❌ unavailable | 7s |
| opus | fable | Read (text file) | ❌ unavailable | 5s |
| opus[1m] | fable | Read (png) | ❌ unavailable | 3.5s |
| sonnet | fable | Bash | ❌ unavailable | 4s |
| opus | opus | Bash | ✅ received | 8s |
| sonnet | opus | Bash | ✅ received | 16s |
Deterministic repro
echo '{"mcpServers":{}}' > /tmp/nomcp.json
# 1. SUCCEEDS — fable advisor, no prior tool_use
mkdir -p /tmp/adv1 && cd /tmp/adv1
claude --debug --advisor fable --model opus \
--strict-mcp-config --mcp-config /tmp/nomcp.json \
-p "Use the advisor tool to review this plan: rename foo() to bar(). Call advisor first, before anything else. Then reply DONE."
# 2. FAILS — identical, except one Bash call precedes the advisor call
mkdir -p /tmp/adv2 && cd /tmp/adv2
claude --debug --advisor fable --model opus \
--strict-mcp-config --mcp-config /tmp/nomcp.json \
-p "Run the bash command 'echo hi'. Then use the advisor tool to review whether that was a good idea. Then reply DONE."
# 3. SUCCEEDS — identical to (2) but advisor=opus
mkdir -p /tmp/adv3 && cd /tmp/adv3
claude --debug --advisor opus --model opus \
--strict-mcp-config --mcp-config /tmp/nomcp.json \
-p "Run the bash command 'echo hi'. Then use the advisor tool to review whether that was a good idea. Then reply DONE."
Check the newest debug log after each:
grep -E "\[AdvisorTool\]" "$(ls -t ~/.claude/debug/*.txt | head -1)"
(2) emits [AdvisorTool] Advisor tool result error: unavailable. (1) and (3) do not.
Isolating "prior tool_use" from "second request in the agent loop"
A tool_use implies a second API request, so those are confounded in the repro above. --continue separates them — turn 1 is pure text, turn 2 calls the advisor, so the advisor call is the session's second request but the transcript holds no tool_use:
mkdir -p /tmp/adv4 && cd /tmp/adv4
claude --debug --advisor fable --model opus --strict-mcp-config --mcp-config /tmp/nomcp.json \
-p "Reply with exactly: HELLO"
claude --debug --advisor fable --model opus --strict-mcp-config --mcp-config /tmp/nomcp.json --continue \
-p "Now use the advisor tool to review this plan: rename foo() to bar(). Then reply DONE."
This succeeds. Swap turn 1 for "Run the bash command 'echo hi'. Then reply HELLO" and the identical turn 2 fails. So the trigger is the tool_use/tool_result in history, not the request index.
Relationship to #73923 (closed)
#73923 reports this as "deterministic when the request contains ToolSearch-loaded deferred tools" and is closed. I believe that identified a special case rather than the cause, and that the behavior still reproduces on 2.1.205:
- Invoking
ToolSearchis itself atool_use. In a stock session it's usually the first one, which is why disabling tool search appears to fix it. - My failing transcript contains no ToolSearch call — dumping it shows exactly
['Bash', 'SERVER:advisor']. ENABLE_TOOL_SEARCH=false(both as an env var and via--settings) does not fix theBash-then-advisor repro.- #73923 reports
claude-opus-4-8as an affected executor. In my runs the executor never matters; only the advisor model does, andopus-as-advisor never failed.
Worth reopening or superseding.
Possibly the same underlying bug
Each of these looks like a facet of the rule above:
- #75971 — "Fable 5 consistently returns
unavailable; Opus 4.8 succeeds under identical config." Correct about the model; the tool-use condition explains why it isn't always. - #72950 — "first
advisor()call worked, the very next one a few tool-turns later errored." That's precisely the boundary. - #67609 — "whenever transcript exceeds ~100K tokens." Transcripts that large invariably contain tool calls; my repro fails at a few hundred tokens.
- #76049 — "many deferred MCP tools, fails at ~56K while a slim-tool session succeeds at ~62K." More deferred tools → a
ToolSearchcall lands earlier. - #67411 / #74530 / #75903 — the latch-off behavior, which is what makes a single hit poison the rest of the session.
Impact
The advisor's own tool description directs the model to orient before consulting it ("If the task requires orientation first — finding files, fetching a source — do that, then call advisor"). With advisorModel: fable, following that instruction guarantees the advisor is dead before it's ever consulted. Only a cold call, before any tool runs, survives — which is the opposite of when a second opinion is worth having.
Net effect: on the default-recommended strongest advisor, the tool is unusable in exactly the long, tool-heavy sessions it's built for. The workaround is advisorModel: opus, which gives up the "stronger reviewer" premise entirely.
Suggested fixes
- Fix the underlying rejection for
claude-fable-5on transcripts containingtool_useblocks. - Until then, stop flattening distinct server-side causes into a bare
unavailable— surface the reason (#66784, #67411 ask for this too). A message namingtool_usewould have saved a lot of collective debugging. - Don't latch the tool off for the session on a single failure, or make
/advisoractually re-enable it (#75903, #73128).
This issue has 7 comments on GitHub. Read the full discussion on GitHub ↗