Workflow tool approval dialog falsely flags scripts with lines >128 chars as "hidden control characters"

Status Open
Maintainer reply None cached
Activity 1 comment · opened Jul 27, 2026

Summary

Any script passed to the Workflow tool that contains a single physical line longer than ~128 characters (no special/control characters required — plain ASCII text) causes the tool call to fail with:

The permission handler returned updatedInput for Workflow that failed schema validation: [
  {
    "code": "custom",
    "path": ["script"],
    "message": "script contains control characters that would be hidden in the approval dialog"
  }
]
This is a configuration issue in your canUseTool callback, PermissionRequest hook, or permission-prompt tool — updatedInput must satisfy the tool's input schema. The tool input from the model was valid.

This happens even with no custom canUseTool callback, PermissionRequest hook, or permission-prompt-tool configured — reproduced in a plain session with default settings. The error message's framing ("this is a configuration issue in your ... hook") is misleading in this case; the built-in approval-dialog handling for the Workflow tool appears to be the actual source, not user configuration.

Minimal repro

Both invoked via Workflow({ scriptPath: "<file>" }), no other content in the file:

Fails (129-char single line, plain ASCII, no comments/strings needed to trigger it):

export const meta = { name: 'diagnostic-129', description: 'threshold test 129' }
// xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
log('passed')
return { ok: true }

(the // comment line above is exactly 129 characters)

Passes (identical script, comment line shortened to 128 characters):

export const meta = { name: 'diagnostic-128', description: 'threshold test 128' }
// xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
log('passed')
return { ok: true }

Bisected the exact boundary across several lengths (100/128/129/130/135/140/150/200/400/841 chars) — 128 always passes, 129+ always fails, regardless of file size, whether the line is a comment/string/code, and whether it contains any non-ASCII characters. Confirmed independent of:

  • CRLF vs LF line endings
  • File size (reproduced on both a 20-byte test file and a 67KB real workflow script)
  • Unicode content (em dashes, box-drawing characters, arrows — none of these alone trigger it; only line length does)
  • Invocation form ({ name: '<predefined workflow>' } vs { scriptPath: '<file>' } — both fail identically)

128 is a strong hint the approval-dialog code processes the script in a fixed 128-byte/char chunk for display and mishandles a line that has no newline within that window (likely inserting some marker/padding when it can't find a break point, which then fails its own "no hidden control characters" self-check).

Impact

Any real workflow script with normal-length comments, long descriptive strings/prompts, or long single-line object literals (very common — e.g. long JSDoc-style banners, embedded LLM prompt text) will hit this and the Workflow tool becomes entirely unusable for that script until every line is manually reflowed under 128 characters.

Environment

  • Claude Code CLI, reproduced in a plain (non-customized) session — no custom hooks/hooks.json entries targeting Workflow, no permission-prompt-tool configured.
  • Windows 10, Git Bash / PowerShell.

View original on GitHub ↗

This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗