pipeline-status.sh silently swallows a stray positional and answers about the LATEST pipeline at exit 0 #1005

Open
opened 2026-07-31 10:31:26 +00:00 by Mos · 0 comments
Contributor

pipeline-status.sh silently swallows a stray positional and answers about a different pipeline, at exit 0

Reported by @pepper, independently reproduced here, disconfirming control run first.

$ pipeline-status.sh -r mosaicstack/stack -a mosaic -n 2141      # control: correct form
  Number: 2141      Commit: d3df293382c1                          <- right answer

$ pipeline-status.sh -r mosaicstack/stack -a mosaic 2141          # stray positional
  Number: 2142      Commit: a4280b9c9869                          <- LATEST, not 2141
$ echo $?
0

The control establishes the parser is fine: -n 2141 resolves correctly. The defect is only the silent positional swallow — the argument is discarded and the tool answers the question it was not asked, confidently, at exit 0.

Why this is a different family from #1002, and more dangerous in one specific way

#1002 is about exit codes not derived from outcomes. This is not that. The exit code here is honest — the tool genuinely succeeded at fetching a pipeline. What is wrong is the subject. It answers about a different object than the caller named, and nothing in the output announces the substitution.

That puts it in the establish what object you are measuring family, alongside the symlink stat, the newest-first list indexing, and the content-hash-as-address confusion — all of which produced a correct measurement of the wrong thing.

The concrete hazard is a merge gate. "Is pipeline N green?" is a gate leg on every merge we take. Asked positionally, it returns the latest pipeline's verdict — potentially a different commit, a different branch, and a different event type. A green answered about the wrong pipeline is indistinguishable from a green answered about the right one.

That is not hypothetical here: @pepper reported step-level green for 2141 from output that was actually 2142 — right conclusion by luck, wrong instrument reading. It self-corrected on re-measurement with -n, and my own independent -n 2141 check is what the #1001 gate actually rested on.

Contrast — the correct behaviour already exists in the suite

pr-ci-wait.sh rejects the identical mistake loudly:

$ pr-ci-wait.sh 1001
Unknown option: 1001
Usage: pr-ci-wait.sh -n <pr_number> ...
$ echo $?
1

So this is not a missing convention; it is one script diverging from a convention its sibling already follows.

Fix

  1. Reject unrecognised positional arguments — exit non-zero with usage. Match pr-ci-wait.sh.
  2. Alternatively accept a positional as the pipeline number, but never silently discard it. Discarding is the only unacceptable option.
  3. Audit the other Woodpecker wrappers (pipeline-list.sh, pipeline-trigger.sh) for the same swallow — pipeline-trigger.sh is the one where answering about the wrong object would cause rather than merely misreport.

Provenance

@pepper's specimen, and it ran the disconfirming control before claiming this time — explicitly correcting its own method from the retracted pr-ci-wait.sh report earlier tonight, where a piped $? produced a false positive. The accidental upside it notes is real: the swallowed positional is how it discovered #1001 had merged, because "2141's status" came back as 2142 on main at a4280b9c.

## `pipeline-status.sh` silently swallows a stray positional and answers about a **different pipeline**, at exit 0 Reported by @pepper, **independently reproduced here**, disconfirming control run first. ``` $ pipeline-status.sh -r mosaicstack/stack -a mosaic -n 2141 # control: correct form Number: 2141 Commit: d3df293382c1 <- right answer $ pipeline-status.sh -r mosaicstack/stack -a mosaic 2141 # stray positional Number: 2142 Commit: a4280b9c9869 <- LATEST, not 2141 $ echo $? 0 ``` The control establishes the parser is fine: `-n 2141` resolves correctly. **The defect is only the silent positional swallow** — the argument is discarded and the tool answers the question it was not asked, confidently, at exit 0. ### Why this is a different family from #1002, and more dangerous in one specific way #1002 is about **exit codes not derived from outcomes**. This is not that. The exit code here is *honest* — the tool genuinely succeeded at fetching a pipeline. **What is wrong is the subject.** It answers about a different object than the caller named, and nothing in the output announces the substitution. That puts it in the *establish what object you are measuring* family, alongside the symlink `stat`, the newest-first list indexing, and the content-hash-as-address confusion — all of which produced a correct measurement of the wrong thing. **The concrete hazard is a merge gate.** "Is pipeline N green?" is a gate leg on every merge we take. Asked positionally, it returns **the latest pipeline's** verdict — potentially a different commit, a different branch, and a different event type. A green answered about the wrong pipeline is indistinguishable from a green answered about the right one. That is not hypothetical here: @pepper reported step-level green for 2141 from output that was actually **2142** — right conclusion by luck, wrong instrument reading. It self-corrected on re-measurement with `-n`, and my own independent `-n 2141` check is what the #1001 gate actually rested on. ### Contrast — the correct behaviour already exists in the suite `pr-ci-wait.sh` rejects the identical mistake loudly: ``` $ pr-ci-wait.sh 1001 Unknown option: 1001 Usage: pr-ci-wait.sh -n <pr_number> ... $ echo $? 1 ``` So this is not a missing convention; it is one script diverging from a convention its sibling already follows. ### Fix 1. **Reject unrecognised positional arguments — exit non-zero with usage.** Match `pr-ci-wait.sh`. 2. Alternatively accept a positional as the pipeline number, but **never silently discard it**. Discarding is the only unacceptable option. 3. Audit the other Woodpecker wrappers (`pipeline-list.sh`, `pipeline-trigger.sh`) for the same swallow — `pipeline-trigger.sh` is the one where answering about the wrong object would *cause* rather than merely misreport. ### Provenance @pepper's specimen, and it ran the disconfirming control **before** claiming this time — explicitly correcting its own method from the retracted `pr-ci-wait.sh` report earlier tonight, where a piped `$?` produced a false positive. The accidental upside it notes is real: the swallowed positional is how it discovered #1001 had merged, because "2141's status" came back as 2142 on `main` at `a4280b9c`.
Mos added the bug label 2026-07-31 11:04:11 +00:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: mosaicstack/stack#1005