Summary
maestro repo bootstrap exits 0 when a bootstrap command fails. The failure
is detected and reported correctly (BOOTSTRAP_COMMAND_FAILED, status: "warning"),
but the process exit code does not reflect it, so maestro repo bootstrap && <next step>
proceeds on a workspace whose dependencies were never installed, and CI goes green.
Related, same report: the per-repository row says state: executed for a command
that failed. There is no per-repository failure state, so the table alone reads as
a success.
I hit this for real: one of five repositories failed its bootstrap on a network
timeout while the other four succeeded. The command exited 0 and the summary line
said warning, so nothing downstream noticed the repository had no dependencies.
Reproduction
# a local origin, so the repro needs no network
mkdir -p /tmp/mrepro/origin /tmp/mrepro/seed
git init -q --bare /tmp/mrepro/origin/demo.git
cd /tmp/mrepro/seed
git init -q -b main .
echo '{}' > package.json
git add -A && git -c user.email=t@t -c user.name=t commit -qm init
git remote add origin /tmp/mrepro/origin/demo.git && git push -q origin main
# a workspace whose single repository has a bootstrap command that fails
cd /tmp/mrepro && maestro init ws
cat > /tmp/mrepro/ws/maestro.yaml <<'YAML'
apiVersion: maestro/v1
kind: Workspace
metadata:
name: repro
spec:
repositories:
- name: demo
remote: /tmp/mrepro/origin/demo.git
branch: main
bootstrap:
strategy: manual
commands:
- sh -c 'echo BOOTSTRAP_RAN; exit 3'
YAML
cd /tmp/mrepro/ws
maestro workspace install --workspace .
maestro repo bootstrap --workspace . --format human; echo "EXIT=$?"
Observed
BOOTSTRAP_RAN
repo bootstrap: warning (1 executed, 0 skipped, 1 issues)
repro
┌────────────────────────┬────────────┬──────────────────────────────────────────┐
│ Repository │ State │ Commands │
├────────────────────────┼────────────┼──────────────────────────────────────────┤
│ demo │ executed │ sh -c 'echo BOOTSTRAP_RAN; exit 3' │
└────────────────────────┴────────────┴──────────────────────────────────────────┘
Issues:
- BOOTSTRAP_COMMAND_FAILED: Bootstrap command failed for demo (…): Command failed with exit code 3: …
EXIT=0
--format json agrees on the content and also exits 0:
{
"data": {
"status": "warning",
"repositories": [{ "commands": ["sh -c 'echo BOOTSTRAP_RAN; exit 3'"], "name": "demo", "skipped": false }],
"issues": [{ "code": "BOOTSTRAP_COMMAND_FAILED", "message": "… exit code 3 …", "path": "…/repos/demo" }]
},
"schemaVersion": 1
}
Expected
A non-zero exit when a bootstrap command fails, and a per-repository state that
distinguishes a failed command from a successful one (failed rather than
executed).
Why this one differs from the documented convention
docs/cli/commands.md deliberately says:
Branch on report status without relying on exit codes
That reads right for the reporting commands — doctor, repo list — where a
finding is information and exit 0 is a fine contract. repo bootstrap is not a
reporting command: it runs commands, and here the report is not describing state it
observed, it is describing an action it was asked to perform and could not. That is
the case an exit code exists for, and it is the one that composes with &&, set -e
and CI without every caller having to pipe through jq.
Verified for contrast: maestro workspace doctor on this same workspace exits 0 with
ok (0 issues) — so today the two are indistinguishable to a caller.
If the convention should hold uniformly, an opt-in (--fail-on-issues, or a
documented note under repo bootstrap that its exit code is not a success signal)
would be enough to make the trap visible.
Environment
- Maestro 0.2.0 (Homebrew, latest release at time of writing)
- macOS 25.6.0, arm64
Summary
maestro repo bootstrapexits 0 when a bootstrap command fails. The failureis detected and reported correctly (
BOOTSTRAP_COMMAND_FAILED,status: "warning"),but the process exit code does not reflect it, so
maestro repo bootstrap && <next step>proceeds on a workspace whose dependencies were never installed, and CI goes green.
Related, same report: the per-repository row says
state: executedfor a commandthat failed. There is no per-repository failure state, so the table alone reads as
a success.
I hit this for real: one of five repositories failed its bootstrap on a network
timeout while the other four succeeded. The command exited 0 and the summary line
said
warning, so nothing downstream noticed the repository had no dependencies.Reproduction
Observed
--format jsonagrees on the content and also exits 0:{ "data": { "status": "warning", "repositories": [{ "commands": ["sh -c 'echo BOOTSTRAP_RAN; exit 3'"], "name": "demo", "skipped": false }], "issues": [{ "code": "BOOTSTRAP_COMMAND_FAILED", "message": "… exit code 3 …", "path": "…/repos/demo" }] }, "schemaVersion": 1 }Expected
A non-zero exit when a bootstrap command fails, and a per-repository state that
distinguishes a failed command from a successful one (
failedrather thanexecuted).Why this one differs from the documented convention
docs/cli/commands.mddeliberately says:That reads right for the reporting commands —
doctor,repo list— where afinding is information and exit 0 is a fine contract.
repo bootstrapis not areporting command: it runs commands, and here the report is not describing state it
observed, it is describing an action it was asked to perform and could not. That is
the case an exit code exists for, and it is the one that composes with
&&,set -eand CI without every caller having to pipe through
jq.Verified for contrast:
maestro workspace doctoron this same workspace exits 0 withok (0 issues)— so today the two are indistinguishable to a caller.If the convention should hold uniformly, an opt-in (
--fail-on-issues, or adocumented note under
repo bootstrapthat its exit code is not a success signal)would be enough to make the trap visible.
Environment