[BUG] Plugin manifest parser rejects UTF-8 BOM in plugin.json — "JSON parse error: Unrecognized token ''"
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?
A plugin.json (and likewise marketplace.json) saved as UTF-8 with BOM makes the plugin fail to load:
Plugin epic-worker has a corrupt manifest file at <marketplace>\epic-worker_v1.4.2\.claude-plugin\plugin.json.
JSON parse error: JSON Parse error: Unrecognized token ''
The file is valid JSON; the "unrecognized token" is the UTF-8 BOM (EF BB BF) being handed to the parser as content. Stripping the BOM fixes loading with no other change.
Why this matters on Windows
UTF-8 with BOM is a pervasive default in the Windows ecosystem — Visual Studio's long-standing save default, Windows PowerShell 5.1's Out-File/Set-Content, and common .editorconfig policies (charset = utf-8-bom). Any of these touching a manifest silently corrupts the plugin from Claude Code's perspective. In our case a formatting hook enforcing a repo-wide [*.json] charset = utf-8-bom rule BOM'd a manifest during routine editing, and the plugin broke on every machine that pulled the marketplace update.
Inconsistency
Claude Code's other JSON config parsing is (at least partly) BOM-tolerant — a .claude\settings.local.json with a BOM loads fine, including its hooks entries. Only the plugin manifest path hard-fails.
What Should Happen?
Parse all JSON configs in UTF-8 both with and without BOM cleanly without errors.
Error Messages/Logs
"JSON parse error: Unrecognized token ''"
Steps to Reproduce
- Take any working plugin; save its
.claude-plugin\plugin.jsonas UTF-8 with BOM (e.g.[IO.File]::WriteAllText($path, $json, [Text.UTF8Encoding]::new($true))in PowerShell). - Install/reload the plugin.
- Loading fails with the error above; all other plugins load normally.
Expected
BOM tolerated when parsing manifests. RFC 8259 §8.1 forbids emitting a BOM but explicitly allows parsers to ignore one "in the interests of interoperability" — and on Windows that interoperability is very real. Skipping a leading EF BB BF before parse (for plugin.json, marketplace.json, and ideally all JSON config uniformly) is a one-line fix.
Claude Model
Other
Is this a regression?
I don't know
Last Working Version
_No response_
Claude Code Version
2.1.220
Platform
Anthropic API
Operating System
Windows
Terminal/Shell
Windows Terminal
Additional Information
_No response_
3 Comments
The same problem is with skill and agent .md files, where the presence of a BOM causes YAML front-matter to be silently ignored.
Reproduced on v2.1.233 (macOS) — not Windows-specific; any
plugin.jsonthat starts with a UTF-8 BOM (EF BB BF) fails to load.Steps:
plugins/bom-plugin/.claude-plugin/plugin.jsoncontaining{"name":"bom-plugin","version":"1.0.0","description":"test"}plus acommands/hello.md.claude plugin validate plugins/bom-pluginpasses, andclaude -p ok --plugin-dir plugins/bom-plugin --debug-file dbg.txtlogsLoaded inline plugin from path: bom-plugin.{ printf '\xEF\xBB\xBF'; cat plugin.json; } > x && mv x plugin.json(equivalent to saving as "UTF-8 with BOM" on Windows / PowerShell 5Out-File).Observed (with BOM):
and in the debug log:
Plugin bom-plugin has a corrupt manifest file at .../plugin.json. Parse error: JSON Parse error: Unrecognized token ''. Removing the 3 BOM bytes makes the same file load with no other change.Expected: a leading UTF-8 BOM is ignored when reading
plugin.jsonandmarketplace.json, the same waysettings.jsonand other JSON config files already tolerate one.Assessment: This looks like a genuine bug. Claude Code's other JSON config readers (settings files,
.mcp.json, etc.) deliberately strip a leading BOM because PowerShell writes UTF-8 with BOM by default, but the plugin manifest and marketplace readers use a plain JSON parser that doesn't. It has always behaved this way (not a regression). The fix is to apply the same BOM-stripping to plugin manifest and marketplace files; the related report about BOMs breaking frontmatter detection in skill/agent.mdfiles is likely the same class of issue.🤖 Generated with Claude Code
Reproduced on 2.1.233 — and it's not Windows-specific; the same failure occurs on Linux.
Steps: created a working local-marketplace plugin, then re-saved its
.claude-plugin/plugin.jsonas UTF-8 with BOM (byte-identical JSON otherwise). Install fails with:Removing the BOM (no other change) makes the same plugin install successfully. I also confirmed the inconsistency you noted: a
.claude/settings.local.jsonsaved with a BOM loads without complaint — only the plugin manifest path hard-fails.Given that RFC 8259 explicitly allows parsers to ignore a leading BOM in the interest of interoperability, and that UTF-8-with-BOM is a common default in Windows tooling, marking this as a confirmed bug.
🤖 Generated with Claude Code