abhigyanpatwari/GitNexus · error · RuntimeError

overlay apply failed and all replacements were rolled back

Error message

overlay apply failed and all replacements were rolled back

What it means

Thrown from the `except` block of `apply_promoted_overlay` when the apply failed but every completed replacement was rolled back cleanly (`rollback_failures` empty, `rollback_complete=True`). The working tree should be back to its pre-apply state; this is the 'safe' failure outcome — no recovery artifact is written.

Source

Thrown at eval/workflow_bench/promotion_apply.py:878

                    rollback_failures.append(f"{replacement['target']}: {type(rollback_exc).__name__}: {rollback_exc}")
            else:
                if not rollback_exchange_is_valid(replacement, temporary_identity, displaced_state):
                    rollback_failures.append(f"{replacement['target']}: rollback parity check failed")
        if rollback_failures:
            preserve_backups = True
            recovery = _write_recovery_artifact(
                root_descriptor,
                repo_root,
                failure=exc,
                rollback_failures=rollback_failures,
                replacements=replacements,
                transaction_state="rollback-incomplete",
            )
            raise RuntimeError(f"overlay apply failed and rollback was incomplete; recovery: {recovery}") from exc
        rollback_complete = True
        if isinstance(exc, (KeyboardInterrupt, SystemExit)):
            raise
        raise RuntimeError("overlay apply failed and all replacements were rolled back") from exc
    finally:
        active_failure = sys.exc_info()[1]
        try:
            if not preserve_backups:
                cleanup_failures: list[str] = []
                cleanup_exception: BaseException | None = None
                for replacement in replacements:
                    for temporary in (replacement["candidate"], replacement["backup"]):
                        if temporary is None:
                            continue
                        try:
                            _unlink_temporary(replacement["parent_descriptor"], temporary)
                        except BaseException as cleanup_exc:
                            cleanup_exception = cleanup_exc
                            cleanup_failures.append(
                                f"{replacement['target']}:{temporary}: {type(cleanup_exc).__name__}: {cleanup_exc}"
                            )
                            break

View on GitHub (pinned to d540b00184)

Solutions

  1. Inspect the chained `__cause__` exception to learn the original failure (drift, parity, staging).
  2. Confirm the tree is clean: `git status --porcelain` and compare `destination_base_digests(overlay)` to your prior capture.
  3. Re-capture `expected_target_bases`/`expected_digest` and retry the apply once the root cause (concurrent writer, etc.) is resolved.
  4. No recovery artifact cleanup is needed because rollback was complete.

Example fix

try:
    apply_promoted_overlay(overlay, expected_target_bases=bases)
except RuntimeError as exc:
    # rollback completed cleanly; inspect original cause
    print('apply rolled back:', exc.__cause__)
    # re-capture and retry after silencing the concurrent writer
    bases = destination_base_digests(overlay)
    apply_promoted_overlay(overlay, expected_target_bases=bases)
Defensive patterns

Strategy: try-catch

Validate before calling

null

Type guard

null

Try / catch

try:
    apply_promoted_overlay(overlay, expected_target_bases=bases)
except RuntimeError as exc:
    if "all replacements were rolled back" in str(exc):
        # safe state — inspect the original cause, re-capture, retry
        original = exc.__cause__
        print("apply aborted cleanly; original cause:", original)
        bases = destination_base_digests(overlay)
        apply_promoted_overlay(overlay, expected_target_bases=bases)
    else:
        raise

Prevention

When it happens

Trigger: Any pre-publication or mid-apply failure (drift at 409/410, staging error, parity failure) where the rollback loop successfully re-swapped all completed targets and verified each displaced state. The exception is re-raised (preserving the original cause via `from exc`) so the caller knows the apply did not publish.

Common situations: Transient drift (409/410) that the rollback fully reversed; a staging error before any exchange completed; KeyboardInterrupt during apply that was caught and rolled back; a single-target parity failure (411) where every earlier swap rolled back.

Related errors


AI-assisted analysis of abhigyanpatwari/GitNexus@d540b00184 (2026-08-12). Data as JSON: /api/errors/0e3f0d1d47c54d98. Report an issue: GitHub.