fix: setup fails closed for invalid configuration arguments - #1005
Conversation
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
|
Codex review: found issues before merge. Reviewed July 17, 2026, 8:14 PM ET / July 18, 2026, 00:14 UTC. Summary Reproducibility: yes. for the original bug at source level: the supplied review and branch tests identify the old malformed --config path and the branch adds direct regression coverage, but this read-only review did not execute the pre-fix binary. Review metrics: 2 noteworthy metrics.
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
Maintainer decision needed
Security Review findings
Review detailsBest possible solution: Keep strict rejection for malformed, unknown, and missing arguments, while preserving legacy duplicate-value behavior unless the setup owner explicitly approves a documented breaking change for all value options. Do we have a high-confidence way to reproduce the issue? Yes for the original bug at source level: the supplied review and branch tests identify the old malformed --config path and the branch adds direct regression coverage, but this read-only review did not execute the pre-fix binary. Is this the best way to solve the issue? Unclear: shared fail-closed parsing is the maintainable fix for malformed setup arguments, but applying strict duplicate rejection to every value option is broader than the reported defect without an explicit compatibility decision. Full review comments:
Overall correctness: patch is incorrect AGENTS.md: found and applied where relevant. Codex review notes: model internal, reasoning high; reviewed against 4518dd87ed2b. Label changesLabel changes:
Label justifications:
Evidence reviewedWhat 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
Review history (7 earlier review cycles)
|
The core bug is real and worth fixing: Merge blockers / required decisions:
Please also avoid maintaining a second unsynchronized option-name list in tests. Expose the canonical internal option set or add an assertion that test coverage and production options stay aligned. Useful live/process proof at the final head:
The current test additions are substantial, but until unknown/equals-form options and the WinUI caller are covered, the implementation still has fail-open/crash edges adjacent to the bug class it is fixing. |
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 6f7a9268-216f-4c97-b7f3-a01ed737eccc
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 6f7a9268-216f-4c97-b7f3-a01ed737eccc
|
Caleb Eden + GitHub Copilot pair-programming follow-up @shanselman Thanks for the detailed review. We replaced the separate value and flag scans with one case-insensitive parser backed by canonical option sets. SetupEngine now accepts both We kept strict duplicate rejection for value options because repeated setup values are ambiguous and fail-closed behavior is safer here. Duplicate bare flags remain idempotent. That policy is now documented and covered by compatibility tests. Tests also combine production-owned option sets with hard-coded contract snapshots so option coverage cannot silently drift. The WinUI path now uses the same fail-closed configuration loader as the CLI. Missing, invalid, unreadable, malformed, directory-path, and JSON At the current head, the full build passes along with 573 SetupEngine tests, 2,863 Shared tests, and 1,718 Tray tests. The PR description and behavior proof have also been updated to reflect the complete change. |
The shared fail-closed loader, canonical CLI option sets, equals-form support, unknown/positional rejection, option-drift coverage, and visible WinUI configuration failure page are meaningful improvements. However, current-head var explicitConfigPath = configPath ?? GetArg(args, "--config");That helper only recognizes Please route the WinUI command-line path through the same canonical parser (or extract a shared parser owner consumed by both hosts) and add direct WinUI/host tests for equals-form, missing value, typo/unknown option, positional input, and valid explicit config. The failure must occur before setup lock acquisition or pipeline startup. Separately, duplicate value rejection is now correctly implemented and documented, but it remains a deliberate compatibility decision. Our recommendation is to preserve first-value-wins unless the setup owner explicitly accepts strict duplicate rejection as the new supported contract. If strict rejection is retained, call that breaking behavior out prominently in migration/CLI docs. The current red test job is the unrelated |
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 6f7a9268-216f-4c97-b7f3-a01ed737eccc
|
Caleb Eden + GitHub Copilot pair-programming follow-up @shanselman Thanks for the follow-up review. We addressed the remaining WinUI argument-parsing gap in The tray-hosted SetupWindow now uses the same canonical fail-closed parser as SetupEngine, with a narrow UI contract. It supports Valid restart and deep-link arguments remain supported. Invalid, self, signed, overflow, or whitespace-padded restart PIDs and unknown post-setup launch targets remain visible to strict parsing instead of being discarded. We retained strict duplicate-value rejection as an intentional compatibility decision and now call it out prominently in the migration/CLI documentation. Direct parser, host-projection, configuration-loading, and lifecycle-ordering tests cover the requested cases. At the current head, the full build passes along with 588 SetupEngine tests, 2,866 Shared tests, and 1,767 Tray tests. The PR description and current-head behavior proof have also been updated. Fresh CI is currently running. |
The strict duplicate-value contract is accepted: SetupEngine should reject repeated value options with exit code 2 rather than preserve legacy first-value-wins behavior. The current head documents and tests that compatibility change, while duplicate bare flags remain idempotent. This resolves the remaining policy/governance question from review. |
What Problem This Solves
Fixes an issue where users running SetupEngine with invalid explicit configuration or malformed arguments could silently load bundled defaults and start setup with settings they did not request. This included missing option values, unknown or misspelled options, unconsumed positional arguments, nonexistent paths, unreadable or malformed files, and semantically empty JSON.
For example, with
--config --headless, the old parser treated--headlessas the config filename. Because that file did not exist, SetupEngine silently loadeddefault-config.jsonwhile separately recognizing--headless. Since those defaults enableCleanBeforeRun, a malformed unattended invocation could unregister the existing app-owned WSL distro and remove setup-managed gateway state before rebuilding it.The tray-hosted setup window also parsed arguments independently, ignored equals syntax and malformed/unknown input, and had no visible recovery path for invalid or JSON
nullconfiguration.Why This Change Was Made
SetupEngine now parses its complete option contract in one shared, fail-closed pass. It supports case-insensitive
--name valueand--name=valuesyntax for value options; rejects unknown options, positional tokens, bare--, values on boolean flags, missing values, and duplicate value options; and preserves idempotent duplicate bare flags. Explicit configuration failures never fall back to bundled defaults.The tray-hosted setup window uses the same parser with a narrow contract for
--configand--no-rollback-on-failure. A focused projection removes only valid tray restart/deep-link host arguments. Invalid, missing, self, signed, overflow, or whitespace-padded restart PIDs and unknown post-setup launch targets remain visible to strict parsing and render the failure page before configuration loading, setup-lock acquisition, or pipeline startup.CLI and WinUI also share expected configuration-load error handling, so missing, unreadable, malformed, directory-path, and JSON
nullconfiguration failures are visible in the existing setup failure UI.User Impact
Operators and automation now receive immediate deterministic errors for malformed setup invocations instead of risking unintended setup or cleanup using bundled defaults. Valid existing invocations continue to work, value options additionally accept equals syntax, legitimate tray restart/deep-link launches remain compatible, and WinUI users receive a visible error with a Close action.
Evidence
Program.Maincoverage for separated/equals syntax, mixed case, embedded equals, missing/blank values, unknown and misspelled options, positional tokens, bare--, flag values, duplicate policy, first-error behavior, and bundled-fallback prevention.CLI behavior screenshots
Links reverified successfully on 2026-07-17.
Change Type
Scope
winnodeValidation
.\build.ps1— passeddotnet test .\tests\OpenClaw.SetupEngine.Tests\OpenClaw.SetupEngine.Tests.csproj --no-restore— 588 passed, 0 failed, 0 skippeddotnet test .\tests\OpenClaw.Shared.Tests\OpenClaw.Shared.Tests.csproj --no-restore— 2,866 passed, 0 failed, 31 conditionally skippeddotnet test .\tests\OpenClaw.Tray.Tests\OpenClaw.Tray.Tests.csproj --no-restore— 1,767 passed, 0 failed, 0 skippedReal Behavior Proof
b31d9b35b7e7b3f478b9f6e326974b10935ab062--wait-for-pid abc; inspected the active SetupWindow through UI Automation.Yes/No/N/A): Yes; all three embedded CLI screenshots returned HTTP 200. A current-head WinUI screenshot was captured locally, and copied UI Automation output is included above.Security Impact
Yes/No): NoYes/No): NoYes/No): NoYes/No): YesYes/No): NoYes, explain the risk and mitigation: Existing setup command-line handling is stricter and supports equals syntax for existing value options. No commands or privileges were added; malformed input is rejected before setup execution.Compatibility and Migration
Yes/No): No for malformed or duplicate-value invocations; valid invocations remain compatibleYes/No): NoYes/No): Only for callers that repeat value optionsReview Conversations
Scott's feedback about unknown options, equals syntax, duplicate policy, synchronized option coverage, visible WinUI configuration failures, and canonical tray-hosted parsing is addressed in the current branch.