Workflow tool: false-positive "control characters" rejection blocks legitimate scripts (repro included)
Environment
- Claude desktop app 1.17377.1.0 (Windows Store build), embedded Claude Code
2.1.197 - Windows 11 Enterprise 10.0.26200
Symptom
Calling the Workflow tool (both {name: "<workflow-name>"} and {scriptPath: "<path>"} forms) on a specific pre-existing, working project workflow file fails every time 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"
}
]
The target tool (Workflow(morning-brief)) is already in the project's permission allowlist, so this isn't a normal approval-dialog prompt — it fails before any dialog would render. Persists across a full machine reboot.
Diagnostics performed (ruling out an actual hidden-character issue)
- Scanned the full 76,179-byte script for ASCII control bytes (0x00–0x1F excl. tab/LF/CR, and 0x7F) — zero found.
- Scanned for zero-width/format Unicode characters (BOM, ZWSP, bidi overrides, etc.) — zero found.
- Created a byte-for-byte ASCII-sanitized copy (all em/en dashes, box-drawing characters, arrows, etc. replaced with plain ASCII equivalents) — still fails identically.
- A minimal ASCII-only script (few lines) — passes instantly.
- An 80KB pure-ASCII padding-only script (same order of magnitude size as the failing script) — passes instantly.
- Bisected the real (ASCII-sanitized) script into two ~36KB halves — both individually pass the permission layer (first half hit a normal JS parse error, not the control-character error; second half, wrapped as a string literal, ran clean).
Conclusion: the failing script contains no actual control characters or hidden Unicode. The error only fires on the full reassembled ~73–76KB script, which is heavy in template literals, JSON.stringify() calls, and regex literals — this looks like a bug in whatever heuristic populates this validation path (possibly miscounting some construct cumulatively across the whole document), with "control characters" being a generic/mislabeled message for an unrelated failure.
Impact: blocks any sufficiently large/complex Workflow script from running at all, with no workaround short of splitting the script into smaller chained sub-workflows.
Workaround identified: splitting the script via the workflow() composition hook into smaller files clears the error (confirmed via the bisection test above).