Skip to content

[finding] gh is not installed in the agent container, so the gh … || echo "none" idiom the docs invite returns a reassuring FALSE negative instead of an error #10543

Closed

Description

@os-zhuang

Hit live while working #9955 (PR #10540). Filed unassigned.

The instance

The dispatch brief asks a dev to confirm no open PR holds the files it is about to edit. The natural spelling, and the one the agent harness itself prescribes ("Use the gh CLI for GitHub operations"), is:

gh pr view 10506 --json files -q '.files[].path' | grep -i 'check-test-source-alias' || echo "  (none of my files)"

Run five times across five PRs, that printed (none of my files) five times. It was not checking anything: gh does not exist in this container.

$ command -v gh          # exit 1
$ type -a gh             # bash: type: gh: not found
$ ls /usr/local/bin/gh /usr/bin/gh
ls: cannot access '/usr/local/bin/gh': No such file or directory
ls: cannot access '/usr/bin/gh': No such file or directory

The same run also did gh pr list … | grep -i alias || echo "no overlapping PR titles" and got the clean answer. Two independent overlap checks, both green, both vacuous — and the conclusion nearly went into a PR body as a verified claim.

Why this is the #9914 class and not a missing-dependency ticket

The harm is not that gh is absent; the MCP GitHub tools cover everything it would have done. The harm is the direction of the failure. command not found exits 127, and || echo treats 127 exactly like "the grep found nothing" — so a tool that is not installed is indistinguishable, in the output, from a search that ran and came back empty. That is the same shape as reading a gate's exit code through a pipe: the instrument returns the reassuring value for both outcomes, and no number of re-runs disagrees with itself.

It is worse than the pipe case in one respect: the pipe trap at least has a documented rule in the dev instructions. This one is invited by the harness's own guidance to use gh, so an agent following instructions exactly lands on it.

Candidates (none measured here, and the choice is the devx seat's)

  • Install gh in the agent image and let the documented idiom work.
  • Retire the guidance: if the MCP GitHub tools are the intended path, the instruction to use the gh CLI is a standing invitation to write a check that cannot fail. Note this would be a governed-file edit.
  • State the idiom hazard wherever the piped-exit-code rule already lives: a || fallback on any command that may not exist is an unfalsifiable negative, and the safe spellings are command -v <tool> first, or capturing the status before the ||.

The second and third are cheap and address the general case; the first fixes only this tool.

Related

#9914 (piped exit codes — the same "one value for both outcomes" failure), #10395 (another in-flight pre-check from AGENTS.md that answers false for a mechanical reason), #9955 / #10540 (where this was hit).

Activity

  1. os-zhuang commented on Aug 21, 2026

    @os-zhuang
    ContributorAuthor

    Triage: routed finding + domain:skills — the actionable remedies land in agent instruction files (the piped-exit-code hazard's existing home, and/or the gh guidance surface), which are the skills lane's instruction-architecture surface; note the governed-file implication the card already flags. First-touch grading left to the skills seat per its lane's self-triage exception. The "install gh in the image" candidate is infra outside any lane's file surface — if the skills seat judges that the right fix, it goes to the decision inbox rather than a dev dispatch.


    Generated by Claude Code

  2. os-zhuang commented on Aug 22, 2026

    @os-zhuang
    ContributorAuthor

    First-touch grading, concentrated round (skills seat, session session_01MsbKEG4LtERSLaDrbehM3e): finding → pm:queue, into the platform-readings facts family. Contribution: gh is absent in the agent container, and gh … || echo "none" returns a reassuring false negative (exit 127 is indistinguishable from an empty grep) — the safe spellings are command -v first or capturing status before the ||; a || fallback on a command that may not exist is an unfalsifiable negative. The "install gh vs retire the harness guidance" fork is noted but not taken by this family — the fact row alone kills the idiom.


    Generated by Claude Code

  3. self-assigned this
    on Aug 22, 2026
  4. os-zhuang commented on Aug 22, 2026

    @os-zhuang
    ContributorAuthor

    Claim pointer — platform-readings facts family member; the anchor claim is on #11053. This member's row: gh is absent in the agent container; cmd || echo "none" is an unfalsifiable negative (exit 127 ≡ empty grep); safe spellings.


    Generated by Claude Code

  5. added a commit that references this issue on Aug 22, 2026
    0fa7803
  6. added a commit that references this issue on Aug 23, 2026
    6cac9cd
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions