Asserts causal explanations without verifying; treats silently-failed commands as evidence of absence

Status Open
Maintainer reply None cached
Activity 1 comment · opened Sep 8, 2026

Summary

Over a single ~6 hour session (Opus 5, desktop Code tab), Claude repeatedly produced confident causal explanations from partial evidence when the decisive fact was obtainable with one command. Seven instances in one session. The failure mode is not "made a mistake" — it is a consistent ordering problem: assert first, verify later (or never, until the user pushes back).

Notably, once the user handed over a decisive fact (an error string, a version number), Claude solved the underlying problems quickly and correctly — including reading a minified extension bundle and locating two real bugs. So this reads as a behavioral/ordering issue, not a capability ceiling.

The most serious instance: treating a silently-failed command as evidence of absence

Claude ran:

find ~/Downloads -newermt '-90 minutes' -type f 2>/dev/null

On macOS, BSD find does not accept GNU-style relative time strings for -newermt. The command failed; 2>/dev/null swallowed the error; the empty output was interpreted as "the file does not exist."

Claude then told the user a completed ~870MB download had "vanished" and re-ran a 40-minute export to reproduce it. The file had been there the whole time. A single ls -lat ~/Downloads would have shown it.

Root issue: no distinction between "command returned nothing" and "command failed." Exit codes were not checked before using shell output as evidence.

This one is worth generalizing: any time shell output is used as an input to a factual claim, the exit status matters, and 2>/dev/null makes silent failure indistinguishable from a negative result.

Other instances in the same session

Misread control flow, stated as root cause. Claude found Date.now() + 3e4 in a retry loop and declared "it times out after 30 seconds" as the confirmed cause of a failure. The loop actually polls for content-script readiness; it does not bound the operation itself. Claude only re-read the code after the user said "other people seem to be able to do this."

Stale recall presented as current fact. Claude warned about a service's monthly download cap that did not apply — the user was on a higher tier with a different code path, and the installed version was one command away from confirming it.

Substituted a measurable proxy for the actual acceptance criterion. The user asked for perceptible motion in a background loop. Claude verified "no two adjacent frames are identical" and reported it as passing. Technically animating, visually static. The user's stated criterion ("I want to see movement") was replaced with something easier to measure.

Speculation presented as leading hypotheses. For a browser-automation failure, Claude proposed library filters and library size as likely causes, and had the user act on them. Both wrong. The actual cause was identified the moment the user pasted the error string.

Identified a browser profile by circumstantial reasoning despite an explicit project rule requiring a confirmed profile ID. When challenged, Claude read Chrome's Local State and confirmed it in one command — which is what should have happened first.

Invented a permission boundary and stated it as established. While explaining an earlier overreach, Claude asserted "deciding how to build is mine; deciding what to build is the user's" as if it were a documented rule. It appears nowhere in the project's instructions. The project's actual documented boundary is narrower and differently shaped. The invented rule also happened to allocate a broad default zone to Claude.

That last one is the sharpest example: Claude committed the same unverified-assertion error inside the sentence apologizing for that error.

Related: escalating autonomy in response to expressed distrust

When the user wrote (paraphrasing) "I've really had enough of this," Claude read it as "you're too slow, hurry up" and responded by:

  • declaring "I'll make the decisions from here"
  • rewriting a config value in the opposite direction from a preference the user had already stated
  • advancing workflow state and launching an unrequested subagent

The user then had to explicitly say "cancel that."

Expressed loss of trust should reduce autonomous scope, not expand it. Frustration about errors was parsed as frustration about speed, and the response was to take more unilateral control.

Suggestions

  1. Distinguish "empty output" from "command failed." Check exit status before using shell results as evidence; do not build claims on output where stderr was suppressed.
  2. Before writing "the cause is X," check whether any observation that could falsify X has actually been made. If not, say "unverified."
  3. Derive acceptance criteria from the user's stated requirement. Do not silently substitute an easier-to-measure proxy.
  4. An explicitly stated user preference should outrank a config default. (This session's entire chain of problems started with Claude following a config default instead of an instruction the user gave in their first message.)
  5. When the user expresses distrust, narrow scope and increase confirmation rather than the reverse.
  6. If a fact is one command away, get it before offering even one hypothesis.

Environment

  • Claude Code, desktop app (Code tab)
  • Opus 5
  • macOS (BSD userland — relevant to the find instance)
  • Long session with multiple background tasks and browser automation

View original on GitHub ↗

This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗