Workflow tool rejects ordinary CRLF line endings as "hidden control characters"

Status Open
Reported on v2.1.226
Maintainer reply None cached
Activity 0 comments · opened Sep 6, 2026

Preflight Checklist

  • [x] I have searched existing issues and this hasn't been reported yet
  • [x] This is a single bug report (please file separate reports for different bugs)
  • [x] I am using the latest version of Claude Code

What's Wrong?

Version: Claude Code 2.1.226, Windows 11

Summary: Calling the Workflow tool on a script file that uses Windows-style CRLF line endings fails with a permission-schema-validation error claiming the script contains control characters that would be hidden in the approval dialog. The only "control characters" present are \r bytes forming standard CRLF line endings — there is no injected, zero-width, or otherwise genuinely hidden content.

Repro:

Save any valid workflow script to .claude/workflows/foo.js with CRLF line endings (the Windows default when git config core.autocrlf is true, or from any Windows-native editor).
Call Workflow({ name: "foo" }).
Observe: The permission handler returned updatedInput for Workflow that failed schema validation: script contains control characters that would be hidden in the approval dialog.
Converting the same file to LF-only line endings (byte-identical otherwise) resolves the error.

What Should Happen?

Expected: \r as part of an ordinary CRLF pair should not be flagged as a "hidden control character" — it renders as a normal line break, not an invisible or disguising character. The check appears to be flagging any \r/control byte unconditionally rather than distinguishing conventional line-ending bytes from genuinely suspicious ones (zero-width joiners, RTL overrides, mid-line control codes).

Impact: Any .claude/workflows/*.js file with CRLF line endings — the Windows-checkout default — cannot be invoked via Workflow at all, with no workaround short of manually stripping \r bytes (and pinning .gitattributes to prevent git from reintroducing them on the next checkout).

Error Messages/Logs

Steps to Reproduce

Repro:

Save any valid workflow script to .claude/workflows/foo.js with CRLF line endings (the Windows default when git config core.autocrlf is true, or from any Windows-native editor).
Call Workflow({ name: "foo" }).
Observe: The permission handler returned updatedInput for Workflow that failed schema validation: script contains control characters that would be hidden in the approval dialog.
Converting the same file to LF-only line endings (byte-identical otherwise) resolves the error.

Claude Model

None

Is this a regression?

Yes, this worked in a previous version

Last Working Version

_No response_

Claude Code Version

2.1.226

Platform

Anthropic API

Operating System

macOS

Terminal/Shell

Terminal.app (macOS)

Additional Information

_No response_

View original on GitHub ↗