openclaw / openclaw/ocm

Upgrade dry-run reports would-switch before candidate validation

Open
#124 1 comment 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

clawsweeper:needs-maintainer-review clawsweeper:needs-product-decision clawsweeper:no-new-fix-pr clawsweeper:source-repro impact:ux-friction issue-rating: 🦞 diamond lobster P2
Dominant language
Rust
Stars
19
Forks
18
Avg merge
16h 43m
Merged PRs (30d)
118

Description

Summary

ocm upgrade --dry-run can report would-switch even when the equivalent real upgrade will fail during candidate preparation.

The dry-run returns before OCM stages or validates the target runtime, so it does not exercise the managed Codex candidate check or other candidate-specific compatibility checks.

Reproduction

With OCM 0.2.34, an environment bound to OpenClaw 2026.7.1, and target version 2026.8.1:

ocm upgrade <env> --version 2026.8.1 --dry-run --json

returns:

{
  "outcome": "would-switch",
  "runtimeReleaseVersion": "2026.8.1",
  "runtimeReleaseChannel": "stable",
  "note": "dry run: no runtime, env, service, or snapshot changed"
}

Running the equivalent real upgrade immediately afterward fails before cutover:

ocm upgrade <env> --version 2026.8.1 --json
upgrade preparation failed before cutover
candidate managed Codex preflight failed

No environment state changed, but the successful dry-run did not predict the real preparation failure.

Root Cause

The runtime-bound upgrade path returns its dry-run result before calling prepare_isolated_upgrade_target():

  • Dry-run return: src/cli/upgrade.rs:2236
  • Candidate preparation and validation: src/cli/upgrade.rs:2270

The existing dry-run test verifies only that no persistent state changes:

tests/upgrade_command_tests.rs:2500

It does not verify parity with candidate preparation failures.

Expected Behavior

A dry-run should execute every non-persistent check required before cutover, including candidate runtime preparation and validation.

For official release targets, OCM should:

  1. Prepare the candidate in disposable staging.
  2. Run the same candidate validation used by the real upgrade.
  3. Remove all temporary staging afterward.
  4. Leave the runtime registry, environment, service, snapshots, and upgrade history unchanged.
  5. Report a failed or would-fail outcome when candidate validation fails.
  6. Report would-switch or would-update only after candidate validation succeeds.

If a candidate check cannot be executed during dry-run, the result must explicitly identify it as not run rather than reporting an unconditional would-switch.

This should use the corrected config-migration ordering tracked in #107 so expected target migrations do not create another dry-run false failure.

Regression Coverage

Add dry-run coverage that verifies:

  • a forced candidate validation failure is reported by dry-run;
  • the same failure is reported by the real upgrade;
  • a valid candidate still reports would-switch;
  • temporary candidate staging is removed;
  • no runtime is published;
  • environment config and binding remain byte-identical;
  • service desired/running state is unchanged;
  • no snapshot or upgrade-history transaction is created;
  • batch dry-run uses the same candidate-validation behavior.

Impact

Operators and automation can receive a successful dry-run, proceed with an upgrade, and then encounter a preparation failure that the dry-run could have detected.

The current output overstates readiness because it validates release resolution and service planning, not the actual candidate runtime.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in src/cli/upgrade.rs around the dry-run return at line 2236 and candidate preparation at line 2270, then read the existing coverage in tests/upgrade_command_tests.rs around line 2500. Run the upgrade tests and compare dry-run with real-upgrade candidate failures. Done means dry-run reports candidate failures, preserves all listed state, cleans staging, and covers valid, batch, and failure cases.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
cli
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
58/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.