Skip to content

Commit 04b9ad3

Browse files
NagyViktNagyVikt
andauthored
fix(add-workers): pass discovered emails to cap-probe + retry discover without --exclude-tmux (#137)
Two cascading bugs in `scripts/codex-fleet/add-workers.sh` made the discovery wrapper report `only 0 healthy unallocated accounts available` and then fail with `no healthy accounts available`, even when ≥1 account in the canonical `agent-auth list` pool passed the 5h<100% / weekly<90% / not-already-active filter. Root cause #1 — cap-probe invoked with no email arguments `pick_accounts()` called `cap-probe.sh "$need"` (only the count). cap-probe's shebang is `<need_n> email1 email2 ...`: after `shift`, it iterates `for email in "$@"` over an empty list, probes nothing, and exits with 0 healthy rows. The wrapper then took the empty result as "0 healthy" and moved on. Root cause #2 — discover-accounts fail-closes when target tmux session is absent `bash discover-accounts.sh --exclude-tmux <session>` runs `tmux list-panes -s -t <session> | sed | sort | tr | sed` under `set -eo pipefail`. On a host where `<session>` doesn't exist on the default tmux server (e.g. running `add-workers.sh` outside the fleet session, or with `CODEX_FLEET_TMUX_SOCKET` unset so the wrapper degrades to the operator's default tmux), tmux exits 1, pipefail kicks in, the helper exits before reaching its python emitter, and the wrapper sees an empty tempfile. The wrapper then treated empty as "all candidates allocated" instead of "tmux filter unusable, retry without it". Fix (surgical, in-file only) 1. After the first discover-accounts call, if the tempfile is empty, retry without `--exclude-tmux`. We still keep `--exclude-active` so accounts already in `fleet-active-accounts.txt` are skipped. 2. Before invoking cap-probe, extract the email column from the discovered TSV and pass each email as a positional arg so cap-probe has something to probe. Empty discovery skips cap-probe entirely. The helper-side bug (discover-accounts.sh exiting 1 when the tmux session is missing instead of treating an empty tmux query as "no live panes to exclude") is left untouched per file-scope contract; the wrapper now compensates for it. Verified on host 2026-05-16: bash -n scripts/codex-fleet/add-workers.sh # exit 0 docker run koalaman/shellcheck:stable …add-workers.sh # only pre-existing findings bash scripts/codex-fleet/add-workers.sh 1 --dry-run # picks admin-mite (1 healthy) bash scripts/codex-fleet/add-workers.sh 2 --dry-run # picks 2 healthy Co-authored-by: NagyVikt <nagy.viktordp@gmail.com>
1 parent 1360461 commit 04b9ad3

1 file changed

Lines changed: 22 additions & 2 deletions

File tree

scripts/codex-fleet/add-workers.sh

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -143,15 +143,35 @@ pick_accounts() {
143143
local discovered_tmp
144144
discovered_tmp="$(mktemp)"
145145
local discover_session="${CODEX_FLEET_SESSION:-codex-fleet${FLEET_ID:+-$FLEET_ID}}"
146+
# Try with --exclude-tmux first (filters accounts already wired to a
147+
# live pane). discover-accounts.sh runs `tmux list-panes -s -t <sess>`
148+
# under `set -eo pipefail`; on a host where that session doesn't exist
149+
# the pipe fails and the helper exits with 0 rows. Retry without
150+
# --exclude-tmux when the first pass returns empty so we don't
151+
# fail-closed and report "0 healthy" while accounts are on disk.
146152
ACTIVE_FILE="$ACTIVE_FILE" bash "$SCRIPT_DIR/lib/discover-accounts.sh" \
147153
--exclude-active --exclude-tmux "$discover_session" \
148154
> "$discovered_tmp" 2>/dev/null || true
155+
if [ ! -s "$discovered_tmp" ]; then
156+
ACTIVE_FILE="$ACTIVE_FILE" bash "$SCRIPT_DIR/lib/discover-accounts.sh" \
157+
--exclude-active \
158+
> "$discovered_tmp" 2>/dev/null || true
159+
fi
149160
if [ -s "$discovered_tmp" ]; then
150161
# Optionally filter through cap-probe to drop capped accounts. If
151162
# cap-probe isn't available, take everything discovered as-is.
152163
if [ -x "$SCRIPT_DIR/cap-probe.sh" ]; then
153-
local healthy_emails
154-
healthy_emails="$(bash "$SCRIPT_DIR/cap-probe.sh" "$need" 2>/dev/null || true)"
164+
# cap-probe.sh requires `<need_n> email1 email2 ...` — without
165+
# the email list it has nothing to probe and exits with 0 healthy
166+
# rows. Feed it every discovered email so the cap filter can
167+
# actually run.
168+
local discovered_emails
169+
discovered_emails="$(awk -F'\t' 'NF>=2 && $2!="" {print $2}' "$discovered_tmp")"
170+
local healthy_emails=""
171+
if [ -n "$discovered_emails" ]; then
172+
# shellcheck disable=SC2086
173+
healthy_emails="$(bash "$SCRIPT_DIR/cap-probe.sh" "$need" $discovered_emails 2>/dev/null || true)"
174+
fi
155175
if [ -n "$healthy_emails" ]; then
156176
# Intersection: discovered ∩ healthy.
157177
while IFS=$'\t' read -r aid email; do

0 commit comments

Comments
 (0)