Fix CLI domain failures exiting with code 0 - #993
Conversation
📝 WalkthroughSummary by CodeRabbit
WalkthroughThe CLI now propagates graph validation failures and non-zero Typer application return values as process exit codes after emitting available error output. ChangesCLI Exit Code Propagation
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
📋 Issue PlannerBuilt with CodeRabbit's Coding Plans for faster development and fewer bugs. View plan used: Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@potpie/context-engine/adapters/inbound/cli/commands/graph.py`:
- Around line 396-398: The downstream ok re-checks are dead code because
_emit_graph_result already raises typer.Exit when payload.get("ok", True) is
False. Remove the redundant post-call checks in _emit_inbox_result,
_emit_quality_result, and _emit_graph_read so those callers just rely on
_emit_graph_result’s exit behavior and no longer repeat unreachable validation
logic.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI (base), Organization UI (inherited)
Review profile: ASSERTIVE
Plan: Pro
Run ID: 2aa8b21a-dd58-423b-8d78-ab3a1b930c76
📒 Files selected for processing (2)
potpie/context-engine/adapters/inbound/cli/commands/graph.pypotpie/context-engine/adapters/inbound/cli/host_cli.py
95e4b30 to
4a54292
Compare
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
potpie/cli/main.py (1)
94-105: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick winRoute
timeline recentthrough graph failure handling.
timeline_recententerscontract()at Line 694 but ultimately calls_emit_read, which emits anok: falsepayload without raising. This bypasses_emit_graph_resultand can still return exit code0for failed timeline graph reads. Use_graph_commandplus_emit_graph_read, or explicitly raisetyper.Exit(EXIT_VALIDATION)after emitting a failed result.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@potpie/cli/main.py` around lines 94 - 105, Update timeline_recent so failed graph reads cannot return exit code 0: route its contract/read flow through _graph_command and _emit_graph_read, or after emitting a failed result explicitly raise typer.Exit(EXIT_VALIDATION). Preserve successful timeline output and ensure the failure path uses the existing graph failure handling.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Outside diff comments:
In `@potpie/cli/main.py`:
- Around line 94-105: Update timeline_recent so failed graph reads cannot return
exit code 0: route its contract/read flow through _graph_command and
_emit_graph_read, or after emitting a failed result explicitly raise
typer.Exit(EXIT_VALIDATION). Preserve successful timeline output and ensure the
failure path uses the existing graph failure handling.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI (base), Organization UI (inherited)
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 1ec10da4-d30a-4567-8ff0-e3670ea2da0c
📒 Files selected for processing (2)
potpie/cli/commands/graph.pypotpie/cli/main.py
Closes #992
Summary
run_cli()usesstandalone_mode=False, socontract()/fail()outcomes (e.g.CapabilityNotImplemented,ambiguous_pot, validation errors) reach the OS process instead of always exiting 0.1when graph workbench results emit"ok": falsevia_emit_graph_result(), closing the gap for in-band failures that never raised an exception (e.g. invalidgraph nudgeevents).Problem
The CLI printed correct structured errors (JSON or human) but often returned exit code
0, so scripts, CI, andcmd && next_steptreated failed commands as successful. Parser/usage errors already exited non-zero; many runtime/domain failures did not.Root causes:
host_cli.run_cli()discarded the return value fromapp(..., standalone_mode=False). Click returns command exit codes instead of propagatingtyper.Exitto the process in that mode._emit_graph_result()printed graph envelopes with"ok": falsewithout raising, so some graph commands exited0despite failure payloads.Solution
adapters/inbound/cli/host_cli.pyexit_code = app(...)andraise typer.Exit(code)when non-zeroadapters/inbound/cli/commands/graph.pyraise typer.Exit(EXIT_VALIDATION)whenokis falseDocumented exit contract (unchanged):
0ok /1validation /2unavailable /3degraded /4auth.Test plan
potpie --json cloud status→ exit2,code: not_implementedpotpie --json graph status(ambiguous pot repo) → exit1,ok: falsepotpie --json graph nudge --event bogus --session s1 --pot <id>→ exit1,ok: falsepotpie pot create(missing name) → exit2(parser error, unchanged)potpie --json graph catalog --pot <id>→ exit0,ok: truepotpie --json cloud status && echo fail→ chain stops (does not print)test_graph_cli_contract,test_cli_usage_errors,test_sentry_daemon,test_cli_ergonomics,test_cli_bootstrap_status(145 tests)Manual verification tip: check Potpie’s exit code without piping (
cmd; echo $?), since$?after| jqreflectsjq, notpotpie.