Workflow tool: false-positive "control characters" rejection blocks legitimate scripts (repro included)

Open 💬 0 comments Opened Jul 1, 2026 by ericshaffer-cpu

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)

  1. Scanned the full 76,179-byte script for ASCII control bytes (0x00–0x1F excl. tab/LF/CR, and 0x7F) — zero found.
  2. Scanned for zero-width/format Unicode characters (BOM, ZWSP, bidi overrides, etc.) — zero found.
  3. 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.
  4. A minimal ASCII-only script (few lines) — passes instantly.
  5. An 80KB pure-ASCII padding-only script (same order of magnitude size as the failing script) — passes instantly.
  6. 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).

View original on GitHub ↗