File: ods/ods-update.sh, function cmd_health (line 944).
Defective code:
services=$("${compose_cmd[@]}" "${compose_args[@]}" ps --services 2>/dev/null || echo "")
...
for service in $services; do
local status
status=$("${compose_cmd[@]}" "${compose_args[@]}" ps --format json "$service" 2>/dev/null \
| jq -r 'if type == "array" then (.[0].State // "unknown") else (.State // "unknown") end' 2>/dev/null \
|| echo "unknown")
if [[ "$status" == "running" ]]; then
log_ok "Service ${service}: running"
else
log_error "Service ${service}: ${status}"
all_healthy=false
fi
done
Behavior:
docker compose ps --services emits one service name per line; the result is stored in a scalar and then iterated with for service in $services, which word-splits on whitespace. A service whose name contains a space (allowed in Compose; some bundled/custom services or user overrides may include spaces, and any multi-word label would be affected) is split into two tokens, and the inner docker compose ps --format json "$service" is run against a fragment — yielding an empty/unknown status.
Impact:
Health reporting becomes wrong for such services: they are reported as not running (all_healthy=false), and a successful stack is flagged unhealthy. Even when service names are single tokens today, the loop is fragile and will misbehave the moment a space appears in any service name.
Fix:
Read the service list line-by-line into an array and iterate over whole lines:
mapfile -t services < <("${compose_cmd[@]}" "${compose_args[@]}" ps --services 2>/dev/null)
for service in "${services[@]}"; do
...
done
(Also guard the empty case so a failed ps does not silently iterate a single empty element.)
File:
ods/ods-update.sh, functioncmd_health(line 944).Defective code:
Behavior:
docker compose ps --servicesemits one service name per line; the result is stored in a scalar and then iterated withfor service in $services, which word-splits on whitespace. A service whose name contains a space (allowed in Compose; some bundled/custom services or user overrides may include spaces, and any multi-word label would be affected) is split into two tokens, and the innerdocker compose ps --format json "$service"is run against a fragment — yielding an empty/unknownstatus.Impact:
Health reporting becomes wrong for such services: they are reported as not running (
all_healthy=false), and a successful stack is flagged unhealthy. Even when service names are single tokens today, the loop is fragile and will misbehave the moment a space appears in any service name.Fix:
Read the service list line-by-line into an array and iterate over whole lines:
(Also guard the empty case so a failed
psdoes not silently iterate a single empty element.)