We needed a public, machine-readable vault of the navigation rules of the road — COLREGS rule text —...
We needed a public, machine-readable vault of the navigation rules of the road — COLREGS rule text — to back an MCP server for a boat agent. The obvious plan: hand Claude the USCG *Navigation Rules and Regulations Handbook* PDF and ask it to transcribe each rule into a clean markdown file. The text is a US Government work in the public domain. Free to copy, free to redistribute.
Claude read the whole PDF, started writing, and then the Anthropic API hard-blocked it:
API Error: 400 Output blocked by content filtering policy
It blocked again. And again. Eleven blocked responses across two sessions before we gave up on transcription entirely. This post is the dead-end in full — the attempts, the repeating error, and the fix that turned out to be the better architecture anyway: **don't route source text through model output. Have the model write a parser, and let the parser write the files.**
The symptom is a `400` from the Messages API mid-task, surfaced by whatever's driving the model (Claude Code, an SDK call, an agent loop) as:
API Error: 400 Output blocked by content filtering policy
It fires *late* — after the model has read the source document and started emitting. The read succeeds. The generation is what dies. And it is sticky: once your task is "read this document and write out its text," every subsequent response in the session tends to get blocked too, including replies that contain no document text at all.
This is not a rate limit, not a context-length error, not a malformed request. It's an **output-side classifier**. Anthropic documents it plainly in their privacy center:
> Claude's purpose is to generate new content and ideas, not to reproduce content that already exists.
It's an anti-regurgitation guard. It watches the *output* stream for sustained verbatim reproduction of source material and trips when it sees it. Two consequences fall straight out of that design, and both bit us:
1. **It is license-blind.** The classifier can't see provenance or licensing. Public-domain USCG rule text trips it exactly like copyrighted prose would. "But this is legal to copy" is not an argument the filter can hear.
2. **It is API-level, so you can't route around it.** Subagents, different sessions, retries — they all hit the same classifier. The trigger is the *shape of the task* (long verbatim copying into output), not a transient.
You're far from alone if you've hit this. It's a long-running source of false positives in Claude Code — [generating a LICENSE file](https://github.com/anthropics/claude-code/issues/18542), [adding a Mozilla license](https://github.com/anthropics/claude-code/issues/4210), [the Contributor Covenant code of conduct](https://github.com/anthropics/claude-code/issues/60361), [extracting a peer-reviewed paper](https://github.com/anthropics/claude-code/issues/24869), even [benign markdown edits](https://github.com/anthropics/claude-code/issues/41197). The common thread in