diff --git a/actions/issueflow-reconcile/issueflow-reconcile.sh b/actions/issueflow-reconcile/issueflow-reconcile.sh index cf7022a..fbe3d16 100644 --- a/actions/issueflow-reconcile/issueflow-reconcile.sh +++ b/actions/issueflow-reconcile/issueflow-reconcile.sh @@ -609,9 +609,22 @@ issue_payload_valid() { # $1 = the requested issue; payload on stdin # one catches an HTTP 200 whose body is `null`, which exits 0 and empties it # just the same. `.number` is checked against the issue asked for, so a # payload about some other issue can never be reconciled as this one. + # THE EMPTINESS CHECK IS NOT REDUNDANT, and it is not stylistic. `jq -e` + # disagrees with itself across versions on empty input: jq 1.7 exits 4 (no + # valid result was ever produced), jq 1.6 exits **0**. This instance's + # runner image (ghcr.io/catthehacker/ubuntu:act-22.04) carries jq 1.6, so + # without this line an EMPTY payload reads as a valid issue payload here — + # the precise thing D3 added this guard to refuse — and the sweep would + # reconcile an issue from a body it never received. Measured both ways, + # 2026-08-05: `jq -e '' /dev/null 2>&1 + ' <<<"$payload" >/dev/null 2>&1 } skipped_tail() { # $1 = skip count, $2 = the issue numbers → the D6 line, or nothing diff --git a/changelog.d/198.md b/changelog.d/198.md index 5a58f55..e9f5f22 100644 --- a/changelog.d/198.md +++ b/changelog.d/198.md @@ -40,6 +40,11 @@ speaks and refuses by name on a runner without it, instead of dying with `command not found` on every sweep. #205 ports it to REST (#198). +- `issue_payload_valid` refuses an empty payload on jq 1.6 as well as 1.7. + `jq -e` exits 4 on empty input under 1.7 and **0** under 1.6, and this + instance's runner carries 1.6 — so the guard #247 D3 added to refuse an + unreadable read was accepting one here (#198). + - The post-merge nudge strips a trailing slash from the server URL, so a forge URL carrying one does not render `//owner/repo` (#198).