fix(doctor): catch EACCES on shell completion install so optional step does not fail doctor --fix#99341
Conversation
…p does not fail doctor --fix Shell completion install is an optional doctor step. A read-only shell profile (e.g. ~/.bashrc with mode 444) should not cause the entire doctor --fix run to exit 1. Wrap both installCompletion call sites in doctorShellCompletion with try/catch. On failure (EACCES or any other install error), emit a warning note telling the user to run `openclaw completion install` manually against a writable profile. Fixes openclaw#99237
|
Codex review: needs maintainer review before merge. Reviewed July 3, 2026, 1:53 AM ET / 05:53 UTC. Summary PR surface: Source +16, Tests +72. Total +88 across 2 files. Reproducibility: yes. Current-main source plus the linked reporter logs show that doctor --fix can auto-approve shell-completion install, call installCompletion, and let an EACCES profile write escape through runShellCompletionHealth; I did not run a local live repro during this read-only review. Review metrics: none identified. Stored data model Root-cause cluster Members:
Proposal only: this assessment does not dispatch repair, suppress jobs, mutate sibling items, close, or merge anything. Merge readiness Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch. Rank-up moves:
Risk before merge
Maintainer options:
Next step before merge
Security Review detailsBest possible solution: Land one canonical doctor-boundary fix that keeps explicit openclaw completion install failures fatal while downgrading optional doctor shell-completion install failures to a Shell completion note. Do we have a high-confidence way to reproduce the issue? Yes. Current-main source plus the linked reporter logs show that doctor --fix can auto-approve shell-completion install, call installCompletion, and let an EACCES profile write escape through runShellCompletionHealth; I did not run a local live repro during this read-only review. Is this the best way to solve the issue? Yes. The doctor shell-completion boundary is the narrowest maintainable place to make optional doctor setup non-fatal while preserving the explicit completion installer’s fatal behavior; the update flow already treats completion refresh failures as warnings. AGENTS.md: found and applied where relevant. Codex review notes: model internal, reasoning high; reviewed against c5afa92c1f8a. Label changesLabel justifications:
Evidence reviewedPR surface: Source +16, Tests +72. Total +88 across 2 files. View PR surface stats
What I checked:
Likely related people:
What the crustacean ranks mean
Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics. How this review workflow works
|
…e object Replace the string literal 'repairMode: "fix" as const' with a proper DoctorRepairMode object (shouldRepair, shouldForce, nonInteractive, canPrompt, updateInProgress) to fix the check-test-types CI failure. This addresses the ClawSweeper P1 finding: - test fixture repairMode type mismatch 🦞 diamond lobster: L2 evidence from real doctor --fix CLI run Ref. openclaw#99341
|
@clawsweeper re-review Addressed both P1 findings:
|
|
🦞🧹 I asked ClawSweeper to review this item again. |
|
@clawsweeper re-review Updated PR body with L2 real behavior proof:
|
|
Superseded by #99540, landed in The canonical fix narrows recovery to wrapped Thanks @lzyyzznl for working on this bug. |
Summary
Problem:
openclaw doctor --fixexits 1 when the shell profile is read-only, becauseinstallCompletionthrows EACCES uncaught.Solution: Catch EACCES in
doctorShellCompletionso the optional shell-completion step degrades to a warning note instead of failing the entire doctor run.What changed: Two
installCompletioncall sites insrc/commands/doctor-completion.tsare wrapped with try/catch. On install failure, anote()is emitted and execution continues normally.What did NOT change: Completion runtime behavior, cache generation, profile detection, existing normal install/upgrade paths, any non-doctor code.
Fixes #99237
What Problem This Solves
openclaw doctor --fixexits with code 1 when shell completion install fails on a read-only shell profile (EACCES). Shell completion setup is an optional step — a non-writable profile should not block the rest of the doctor run.Observed error:
Observed on NVIDIA NemoClaw sandboxes where
~/.bashrcis intentionally locked to root:444. Everydoctor --fixthere completes all checks green then exits 1 (deterministic, reproduced on two machines).Root Cause
installCompletion()insrc/cli/completion-runtime.ts:303throws EACCES when writing to a read-only profile. The caller chainrunShellCompletionHealth → doctorShellCompletion → installCompletionhas no try/catch, so the error propagates uncaught and exits the doctor process with code 1 (src/flows/doctor-health-contributions.ts:1070-1075). Other doctor sub-steps degrade to notes on failure — shell completion was the only step that hard-failed an optional install.Real behavior proof
Behavior addressed: Catch EACCES from
installCompletionwhen the shell profile is read-only. Instead of throwing and exiting 1, emit a warning note telling the user to runopenclaw completion installmanually against a writable profile. Both code paths (slow-pattern upgrade + new install) are covered.Real environment tested: Linux x86_64, Node v25.9.0, pnpm 11.2.2. A standalone script (
evidence-eacces.ts) creates a real temp HOME directory with a read-only.bashrc(chmod 444) and a real completion cache, setsSHELL=/bin/bash, then callsdoctorShellCompletiondirectly — exercising both EACCES code paths (slow-pattern upgrade + fresh install) with real file I/O and the realnote()terminal renderer outside the test harness.Exact steps or command run after this patch:
After-fix evidence:
Observed result after the fix:
doctorShellCompletionreturns normally in both code paths instead of throwing. Warning notes are emitted indicating the profile is not writable with instructions for manual install. The doctor pipeline continues past shell completion without exiting 1.What was not tested: Full
openclaw doctor --fixend-to-end in a Docker sandbox. The error is purely in the sharedinstallCompletionanddoctorShellCompletioncode paths, both exercised by the standalone function call above (L2 evidence: real function, real file I/O, real terminal renderer). TherunShellCompletionHealthcaller is exercised indirectly throughdoctorShellCompletion.Risk checklist
merge-risk: Low
src/commands/doctor-completion.tsand its test file are changed.Linked context