Original Reddit post

A staple of the Claude Code Write and Edit tools has always been file read enforcement. Claude must read a file before it is allowed to edit it. You may have seen it before, where the Write tool denies Claude the ability to write to a file until it has read it. Recently this has been changed to exclude the 5-family of models. The harness checks if the model is in the 5-family and allows the write or edit to continue blindly. The major side effect we’ve observed of this enforcement skip is test clobbering, especially with Fable. If a task includes writing new tests Fable will clobber existing tests in files when writing new tests. This is especially evident if Fable believes it already knows what tests exist from other sources. Confused it was happening, we explicitly prompted Fable, Opus, and Sonnet to attempt to write to a file without reading it, all were successful (and all were confused it worked, quoting the write tool’s documentation). Opus dug into the bun file: let state = ctx.readFileState.get(path); if (!state || state.isPartialView) { let guardSkipped = !state // never read && !isNotebook(path) // extname !== “.ipynb” && !I6t(model) // model NOT in enforcement set && XCt(WriteTool, path, ctx); // reading it was auto-allowed anyway log(“tengu_write_tool_not_read_hypothetical”, { wouldHaveResult, guardSkipped, modelBucket }); if (!guardSkipped) return { result: false, message: “File has not been read yet. Read it first before writing to it.”, errorCode: 2 }; return { result: true }; // ← guard skipped, write proceeds } The deciding term is I6t: function I6t(e) { return rs_.has(Ba(e)) } function Ba(e) { return e.replace(/[1m]$/i, “”) } rs_ = new Set([“claude-opus-4-6”,“claude-haiku-4-5”,“claude-opus-4-5”,“claude-opus-4-1”, “claude-opus-4-0”,“claude-sonnet-4-5”,“claude-sonnet-4-0”, “claude-3-7-sonnet”,“claude-3-5-sonnet”,“claude-3-5-haiku”]); Opus warned “the deobfuscation is inference from minified code…don’t lean on it if you report this upstream”, so take it with a grain of salt, but this appears to intentional. My guess is they believe they’re trained these models to not clobber code well enough to avoid the check (and maybe reduce token input?). In any case it has not been our experience that these models can handle this concession. If it is an intentional change the Write tool’s own description still promises the guard fires, so at the very least they’ve failed to update the documentation context provided to the model. We’ve worked around the issue with a PreToolUse hook that explicitly checks if a Read operation has occurred in the current session before both Write and Edit tool invocations. Definitely curious if anyone else has run into this. submitted by /u/myninerides

Originally posted by u/myninerides on r/ClaudeCode