FoolDev Claude Opus 4.7 commited on
Commit
f78bca7
·
1 Parent(s): 385ed94

check.sh: footgun-grep for VAR="$(cmd 2>/dev/null | filter)" silent-exit

Browse files

Captures the heal-hf bug class (commit 385ed94) as a regression
guard. Pattern: top-level variable assignment whose `$(...)` body
both suppresses stderr (`2>/dev/null`) AND contains a pipe. Under
`set -euo pipefail`, the first command's failure propagates
through the pipeline (`pipefail`), set -e aborts on the
assignment, and any subsequent `[[ -z "${VAR}" ]]` empty-check
never runs — the user sees only `make: *** Error 1`.

The `2>/dev/null` is the load-bearing tell: a script author who
suppresses stderr knows the command can fail loudly. Combined
with a pipeline, that's the exact silent-exit footgun. Without
the `2>/dev/null`, the failing command would print its own error
and the user would have a clue; we don't flag those.

Regex: `^\s*[A-Za-z_][A-Za-z0-9_]*=("?)\$\([^)]*2>/dev/null[^|]*\|`
Walks scripts/*.sh via grep -R. Currently passes — the heal-hf
fix already uses the if-form.

Failure message points at the fix recipe:
if VAR="$(cmd 2>/dev/null)"; then
VAR2="$(filter <<<"${VAR}")"
fi
and at commit 385ed94 for the original incident.

Header comment at the top of check.sh updated to enumerate this
as check #6 (was 5 checks), parallel to the existing dash/dot
footgun (#5) that traces back to 6f2884f82677d0.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

Files changed (2) hide show
  1. CHANGELOG.md +14 -0
  2. scripts/check.sh +36 -1
CHANGELOG.md CHANGED
@@ -7,6 +7,20 @@ and documentation**, not the underlying base model.
7
 
8
  ## [Unreleased]
9
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
10
  ### Fixed
11
  - `scripts/heal_hf_pull.sh` silent-exit when the target tag isn't
12
  pulled. The blob-locator line was
 
7
 
8
  ## [Unreleased]
9
 
10
+ ### Added
11
+ - `scripts/check.sh` now greps for the `VAR="$(cmd 2>/dev/null | filter)"`
12
+ silent-exit pattern that bit `heal_hf_pull.sh` (commit 385ed94).
13
+ Pattern fires on any top-level assignment whose `$(...)` body
14
+ both suppresses stderr (`2>/dev/null`) and pipes through a
15
+ filter — the exact combination where `set -e + pipefail`
16
+ swallows the failure of the first command and aborts the script
17
+ before any explicit `[[ -z "${VAR}" ]]` check can run, leaving
18
+ the user staring at `make: *** [Makefile:N: <target>] Error 1`
19
+ with no diagnostic. Suggested fix in the failure message:
20
+ `if VAR=$(cmd 2>/dev/null); then VAR2=$(filter <<<"${VAR}"); fi`.
21
+ Currently passes (the heal-hf fix already uses the if-form);
22
+ pre-commit hook + `make check` now block regressions.
23
+
24
  ### Fixed
25
  - `scripts/heal_hf_pull.sh` silent-exit when the target tag isn't
26
  pulled. The blob-locator line was
scripts/check.sh CHANGED
@@ -9,6 +9,8 @@
9
  # 4. python3 -m py_compile on every *.py (catches actual syntax errors)
10
  # 5. grep -E for the dash/dot filename footgun (the one we shipped in 6f2884f
11
  # and had to fix in 82677d0)
 
 
12
  #
13
  # Exit non-zero on any failure. Designed to run from .git/hooks/pre-commit.
14
  #
@@ -118,7 +120,40 @@ else
118
  echo " [ ok ] no stale dot-pattern matches"
119
  fi
120
 
121
- # ---- 6. Modelfile <-> bridge files sync -----------------------------------
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
122
  #
123
  # 'Modelfile' (consumed by 'ollama create -f Modelfile') and the root-level
124
  # 'template' / 'system' / 'params' files (consumed by HF's Ollama bridge,
 
9
  # 4. python3 -m py_compile on every *.py (catches actual syntax errors)
10
  # 5. grep -E for the dash/dot filename footgun (the one we shipped in 6f2884f
11
  # and had to fix in 82677d0)
12
+ # 6. grep -E for the VAR="$(cmd 2>/dev/null | filter)" silent-exit pattern
13
+ # under set -e + pipefail (the one we shipped in d87bc64 and fixed in 385ed94)
14
  #
15
  # Exit non-zero on any failure. Designed to run from .git/hooks/pre-commit.
16
  #
 
120
  echo " [ ok ] no stale dot-pattern matches"
121
  fi
122
 
123
+ # ---- 6. footgun: VAR="$(cmd 2>/dev/null | filter)" silent-exit pattern -----
124
+ #
125
+ # Under `set -euo pipefail`, a direct command substitution like
126
+ # VAR="$(ollama show "${TAG}" 2>/dev/null | awk ...)"
127
+ # silently kills the script when ollama show fails: pipefail
128
+ # propagates the non-zero exit through the pipeline, set -e
129
+ # aborts on the assignment, and the explicit `[[ -z "${VAR}" ]]`
130
+ # check below it never runs. The user sees only
131
+ # make: *** [Makefile:N: <target>] Error 1
132
+ # with no diagnostic. We shipped this exact bug in
133
+ # scripts/heal_hf_pull.sh and only caught it this session by
134
+ # running `make heal-hf` against an empty store — see commit
135
+ # 385ed94 for the fix recipe: split the assignment with
136
+ # if VAR="$(cmd 2>/dev/null)"; then
137
+ # VAR2="$(filter <<<"${VAR}")"
138
+ # fi
139
+ # The `2>/dev/null` is the tell — its presence says "this command
140
+ # can fail loudly, we want to suppress the noise" — which is
141
+ # exactly the case where set -e + pipefail silently kills.
142
+
143
+ blue "[*] grep: forbidden VAR=\$(... 2>/dev/null | ...) silent-exit pattern"
144
+ if grep -RnE '^\s*[A-Za-z_][A-Za-z0-9_]*=("?)\$\([^)]*2>/dev/null[^|]*\|' \
145
+ --include='*.sh' \
146
+ --exclude-dir=.git \
147
+ scripts/ ; then
148
+ red " [FAIL] silent-exit substitution under set -e + pipefail."
149
+ red " Rewrite as 'if VAR=\$(cmd 2>/dev/null); then VAR2=\$(filter <<<\"\${VAR}\"); fi'."
150
+ red " See commit 385ed94 for the bug we shipped and the fix recipe."
151
+ FAIL=1
152
+ else
153
+ echo " [ ok ] no silent-exit substitution patterns"
154
+ fi
155
+
156
+ # ---- 7. Modelfile <-> bridge files sync -----------------------------------
157
  #
158
  # 'Modelfile' (consumed by 'ollama create -f Modelfile') and the root-level
159
  # 'template' / 'system' / 'params' files (consumed by HF's Ollama bridge,