[BUG] Agent .md silently skipped when file has CRLF line endings AND unquoted description contains ": " (colon+space) — deterministic minimal repro
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?
Summary
A custom agent file in .claude/agents/ is silently skipped (never registered; --agent <name> not found / Agent type '<name>' not found) when both of the following hold:
- the file has CRLF line endings, and
- the unquoted
description:value contains:(a colon followed by a space), e.g.description: My agent [ref: ABC-123].
Either condition alone is fine: the same file with LF endings registers correctly, and CRLF files without : in the description register correctly. There is no warning or error anywhere — the agent is just missing from the available-agents list, which makes this extremely hard to debug.
This looks like a plausible root cause for at least #76499 (files there are confirmed CRLF, and a deterministic subset of agents never loads) and possibly #73865 ("identical siblings work fine") — see "Relation to existing issues" below.
Environment
- Claude Code 2.1.218 (native install,
~/.local/bin/claude); the symptom was first observed on 2.1.177 with real-world files, and the minimal pair below was isolated on 2.1.218 - Windows 11 Pro (10.0.26200), Git Bash
- Repro is in a clean empty directory (not a git repo, no
settings.json, no hooks, no plugins) — project/user settings are ruled out
Minimal repro
mkdir -p repro/.claude/agents && cd repro
# LF + ": " in description -> registers fine
printf -- '---\nname: agent-lf\ndescription: test [ref: ABC-123]\ntools: Read\n---\nReply with exactly: LF_OK\n' \
> .claude/agents/agent-lf.md
# CRLF + ": " in description -> silently skipped
printf -- '---\r\nname: agent-crlf\r\ndescription: test [ref: ABC-123]\r\ntools: Read\r\n---\r\nReply with exactly: CRLF_OK\r\n' \
> .claude/agents/agent-crlf.md
claude -p "Follow your system prompt." --agent agent-lf --max-turns 1
# -> LF_OK
claude -p "Follow your system prompt." --agent agent-crlf --max-turns 1
# -> --agent 'agent-crlf' not found. Available agents: claude, claude-code-guide, Explore,
# general-purpose, Plan, agent-lf, statusline-setup
The same registration failure is observed when launching via the Agent/Task tool (subagent_type: "agent-crlf" → Agent type 'agent-crlf' not found).
Isolation matrix (all tested on 2.1.218, clean directory)
| Line endings | description value contains | Result |
|---|---|---|
| LF | [ref: ABC-123] (colon+space, unquoted) | ✅ registers |
| CRLF | plain ASCII, no colon | ✅ registers |
| CRLF | colon without space ([ref:ABC-123]) | ✅ registers |
| CRLF | multibyte UTF-8 (Japanese text, é), no colon+space | ✅ registers |
| CRLF | YAML comment line in frontmatter | ✅ registers |
| CRLF | quoted scoped tools entries (- "Write(docs/**)") | ✅ registers |
| CRLF | [ref: ABC-123] (colon+space, unquoted) | ❌ silently skipped |
| CRLF | same value but double-quoted (description: "test [ref: ABC-123]") | ✅ registers |
Extra fields (model, maxTurns, permissionMode) were also tested individually under CRLF and are not involved.
Hypothesis (mechanism)
An unquoted plain scalar containing : is technically ambiguous YAML. The frontmatter parser appears to tolerate this ambiguity when lines end in \n, but fails when the line ends in \r\n — and a parse failure causes the whole agent file to be dropped silently.
Why this clusters on Windows
git config core.autocrlf=true (a very common Windows default) converts working-tree files to CRLF on checkout. So agent files that are committed with LF and work for macOS/Linux teammates silently vanish on Windows machines — and only those whose descriptions contain : , which makes the failing subset look arbitrary ("identical siblings work fine").
Relation to existing issues (hypothesis — for the reporters to check)
- #76499: all 14 files are reported as CRLF, and the same 5 agents deterministically fail while 9 load. Prediction: the 5 failing files have
:in their unquoteddescription, the 9 working ones don't. - #73865: one agent never registers while structurally identical siblings work, on Windows. Same prediction for the failing file's
description.
Workarounds (verified)
- Quote the description:
description: "test [ref: ABC-123]"— works even with CRLF. - Normalize the file to LF, and pin it with
.gitattributes:.claude/agents/*.md text eol=lf. - Avoid
:inside unquoted description values.
Suggested fixes
- Normalize
\r\nbefore frontmatter parsing (split on/\r?\n/or strip trailing\rper line). - Independent of the fix above: when an agents file fails frontmatter parsing, emit a visible warning naming the file instead of skipping silently. The silence is what turns a one-character YAML quirk into hours of debugging.
What Should Happen?
The CRLF agent file should register exactly like the LF one does (line endings should not affect agent discovery). At minimum, when an agent file fails frontmatter parsing, Claude Code should emit a visible warning naming the file instead of silently skipping it.
Error Messages/Logs
--agent 'agent-crlf' not found. Available agents: claude, claude-code-guide, Explore, general-purpose, Plan, agent-lf, statusline-setup
(No other error or warning is emitted anywhere — the agent file is skipped silently. When invoked via the Agent/Task tool instead of --agent, the error is: Agent type 'agent-crlf' not found.)
Steps to Reproduce
- On Windows, create a clean empty directory and an agents folder inside it:
mkdir -p repro/.claude/agents && cd repro(Git Bash) - Create two agent files that are byte-identical except for line endings — both have an unquoted
descriptioncontaining:(colon+space):
# LF version
printf -- '---\nname: agent-lf\ndescription: test [ref: ABC-123]\ntools: Read\n---\nReply with exactly: LF_OK\n' > .claude/agents/agent-lf.md
# CRLF version
printf -- '---\r\nname: agent-crlf\r\ndescription: test [ref: ABC-123]\r\ntools: Read\r\n---\r\nReply with exactly: CRLF_OK\r\n' > .claude/agents/agent-crlf.md
- Run the LF agent:
claude -p "Follow your system prompt." --agent agent-lf --max-turns 1→ repliesLF_OK(registers correctly) - Run the CRLF agent:
claude -p "Follow your system prompt." --agent agent-crlf --max-turns 1→--agent 'agent-crlf' not found(silently skipped; it is also absent from the available-agents list) - Control experiments (see isolation matrix in the description): removing the
:from the CRLF file's description makes it register; double-quoting the description also makes it register; so the failure requires CRLF and an unquoted:in the description.
Claude Model
None
Is this a regression?
I don't know
Last Working Version
_No response_
Claude Code Version
2.1.218 (Claude Code)
Platform
Anthropic API
Operating System
Windows
Terminal/Shell
Non-interactive/CI environment
Additional Information
_No response_
This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗