[Bug] Tool input renderer surfaces "Unhandled node type: string" in permission prompt
Bug Description
Unhandled node type: string fallback prompt when rendering complex tool input
Environment
- Claude Code CLI (latest at time of report, 2026-04-17)
- Model: Claude Opus 4.7 (1M context), id claude-opus-4-7
- Platform: macOS 26, Darwin 25.4.0, zsh
Symptom
When Claude invokes a tool whose input contains a sufficiently complex shell string (multi-line bash one-liner with nested quoting, jq filters, while
... do ... done loops, etc.), the tool-use preview in the terminal renders as:
Monitor(GitHub release workflow status for v0.3.141)
prev_main="";prev_tag="";while true;do out=$(gh run list ... )
GitHub release workflow status for v0.3.141
Unhandled node type: string
Do you want to proceed?
❯ 1. Yes
- No
Instead of the normal permission-prompt UI (which would say e.g. "Claude wants to use Monitor" with a visible diff/summary of the arguments), the
user gets a generic Do you want to proceed? prompt and the cryptic Unhandled node type: string line inserted into the preview.
Expected
- Either a properly rendered tool preview with argument highlighting
- Or the standard permission prompt with a clean description — not a generic proceed/cancel bound to an internal renderer error
Reproduction (best effort)
Invoke a tool (e.g. Monitor or Bash) with a command argument similar to:
prev_main="";prev_tag="";while true;do out=$(gh run list --limit 5 --json databaseId,event,headBranch,status,conclusion,displayTitle 2>/dev/null ||
echo "[]");main=$(echo "$out"|jq -r '[.[]|select(.headBranch=="main" and (.displayTitle|contains("v0.3.141")))][0]|"\(.status) \(.conclusion)
\(.databaseId)"');...done
The preview renderer appears to fail on this input — likely because the AST/markdown node tree for the pretty-printer hits a string node without a
registered handler, and falls back to a generic confirmation dialog.
Impact
- User cannot see a readable diff of what the tool will run — only the raw command string plus an error line
- Unhandled node type: string is an internal developer message that shouldn't be surfaced to end users
- The generic Do you want to proceed? can be confused with the normal permission prompt, which is a safety-critical UI
Guess at root cause
Something in the tool-input renderer — probably the syntax-highlighted bash/diff view — has a switch over AST node types that doesn't cover the
string literal case, so it throws/returns a fallback marker that gets mixed into the prompt.
Suggested fix
- Add a default handler for string (and any other missing) AST node types that just prints the value verbatim
- Ensure renderer errors are logged internally, not shown inline with the permission prompt
Environment Info
- Platform: darwin
- Terminal: zed
- Version: 2.1.112
- Feedback ID: 27cdcd97-eb02-415a-a1ae-ad4d34c644ef
Errors
[{"error":"Error: NON-FATAL: Lock acquisition failed for /Users/bobby/.local/share/claude/versions/2.1.112 (expected in multi-process scenarios)\n at Od_ (/$bunfs/root/src/entrypoints/cli.js:2748:2177)\n at Ke6 (/$bunfs/root/src/entrypoints/cli.js:2748:1257)\n at processTicksAndRejections (native:7:39)","timestamp":"2026-04-17T14:42:58.798Z"},{"error":"AxiosError: timeout of 5000ms exceeded\n at <anonymous> (/$bunfs/root/src/entrypoints/cli.js:115:13335)\n at emit (node:events:92:22)\n at <anonymous> (/$bunfs/root/src/entrypoints/cli.js:114:3321)\n at request (/$bunfs/root/src/entrypoints/cli.js:117:2467)\n at async QC6 (/$bunfs/root/src/entrypoints/cli.js:439:4055)\n at processTicksAndRejections (native:7:39)","timestamp":"2026-04-17T14:43:18.818Z"},{"error":"Error: Request was aborted.\n at makeRequest (/$bunfs/root/src/entrypoints/cli.js:50:3448)\n at processTicksAndRejections (native:7:39)","timestamp":"2026-04-17T14:43:41.701Z"},{"error":"Error: Request was aborted.\n at makeRequest (/$bunfs/root/src/entrypoints/cli.js:50:3448)\n at processTicksAndRejections (native:7:39)","timestamp":"2026-04-17T14:43:50.502Z"},{"error":"AxiosError: timeout of 5000ms exceeded\n at <anonymous> (/$bunfs/root/src/entrypoints/cli.js:115:13335)\n at emit (node:events:92:22)\n at <anonymous> (/$bunfs/root/src/entrypoints/cli.js:114:3321)\n at request (/$bunfs/root/src/entrypoints/cli.js:117:2467)\n at async QC6 (/$bunfs/root/src/entrypoints/cli.js:439:4055)\n at processTicksAndRejections (native:7:39)","timestamp":"2026-04-17T14:44:01.703Z"},{"error":"AxiosError: timeout of 5000ms exceeded\n at <anonymous> (/$bunfs/root/src/entrypoints/cli.js:115:13335)\n at emit (node:events:92:22)\n at <anonymous> (/$bunfs/root/src/entrypoints/cli.js:114:3321)\n at request (/$bunfs/root/src/…
Note: Content was truncated.
This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗