Context
compose_file_args() in scripts/lib/selfhost-deploy-common.sh:103-121 calls exit 1 (line 118) on a missing compose file, but every caller invokes it through a process substitution feeding mapfile:
mapfile -t compose_args < <(compose_file_args)
compose_file_args therefore always runs in a subshell; its exit 1 only kills that subshell. mapfile itself still returns 0 (an empty/partial read), so set -e never fires. Verified concretely: bash -c 'set -e; mapfile -t arr < <(false); echo "reached, len=${#arr[@]}"' prints reached, len=0 and exits 0.
Failure scenario: an operator with a stale/mistyped docker-compose.override.yml reference, or SELFHOST_COMPOSE_FILES pointing at a nonexistent file, gets the intended error: compose file not found: X printed to stderr, but the calling script (deploy-selfhost-image.sh:111, deploy-selfhost-prebuilt.sh:107, selfhost-post-update-check.sh:25, selfhost-post-update-regression-gate.sh:44) keeps running with an empty/truncated compose_args, invoking docker compose ... pull/up/ps with the wrong -f set instead of aborting cleanly.
Requirements
Replace the mapfile -t compose_args < <(compose_file_args) idiom at all 4 call sites with one that actually propagates compose_file_args's exit code under set -e — e.g. a checked plain command-substitution assignment (x=$(compose_file_args) does propagate failure; verified via bash -c 'set -e; foo(){ exit 3; }; x=$(foo); echo after' exiting 3, never reaching echo), or an explicit non-empty check on compose_args immediately after the mapfile call. Do not change compose_file_args's own logic — only how its callers consume its exit status.
Deliverables
Test Coverage Requirements
test/unit/selfhost-deploy-common.test.ts exists but does not cover compose_file_args today. Add a test asserting the exit-propagation fix.
Expected Outcome
A missing/mistyped compose file reference during a self-host deploy aborts the deploy script immediately with the intended error, instead of silently continuing with an empty or truncated compose-file argument list.
Links & Resources
scripts/lib/selfhost-deploy-common.sh:103-121 (the function), lines 111/107/25/44 in the 4 caller scripts named above
Context
compose_file_args()inscripts/lib/selfhost-deploy-common.sh:103-121callsexit 1(line 118) on a missing compose file, but every caller invokes it through a process substitution feedingmapfile:compose_file_argstherefore always runs in a subshell; itsexit 1only kills that subshell.mapfileitself still returns 0 (an empty/partial read), soset -enever fires. Verified concretely:bash -c 'set -e; mapfile -t arr < <(false); echo "reached, len=${#arr[@]}"'printsreached, len=0and exits 0.Failure scenario: an operator with a stale/mistyped
docker-compose.override.ymlreference, orSELFHOST_COMPOSE_FILESpointing at a nonexistent file, gets the intendederror: compose file not found: Xprinted to stderr, but the calling script (deploy-selfhost-image.sh:111,deploy-selfhost-prebuilt.sh:107,selfhost-post-update-check.sh:25,selfhost-post-update-regression-gate.sh:44) keeps running with an empty/truncatedcompose_args, invokingdocker compose ... pull/up/pswith the wrong-fset instead of aborting cleanly.Requirements
Replace the
mapfile -t compose_args < <(compose_file_args)idiom at all 4 call sites with one that actually propagatescompose_file_args's exit code underset -e— e.g. a checked plain command-substitution assignment (x=$(compose_file_args)does propagate failure; verified viabash -c 'set -e; foo(){ exit 3; }; x=$(foo); echo after'exiting 3, never reachingecho), or an explicit non-empty check oncompose_argsimmediately after themapfilecall. Do not changecompose_file_args's own logic — only how its callers consume its exit status.Deliverables
deploy-selfhost-image.sh,deploy-selfhost-prebuilt.sh,selfhost-post-update-check.sh,selfhost-post-update-regression-gate.sh) actually abort whencompose_file_argsfails.selfhost-deploy-common.shif filed) or an inline test proving a missing compose file now aborts the calling script instead of continuing with empty/truncated args.Test Coverage Requirements
test/unit/selfhost-deploy-common.test.tsexists but does not covercompose_file_argstoday. Add a test asserting the exit-propagation fix.Expected Outcome
A missing/mistyped compose file reference during a self-host deploy aborts the deploy script immediately with the intended error, instead of silently continuing with an empty or truncated compose-file argument list.
Links & Resources
scripts/lib/selfhost-deploy-common.sh:103-121(the function), lines 111/107/25/44 in the 4 caller scripts named above