Yeachan-Heo/oh-my-codex · error · Error

priorScaleDownCleanup.error

Error message

priorScaleDownCleanup.error

What it means

Thrown when reconcileScaleDownCleanupDebt fails during shutdown (returns ok:false); its error string is rethrown verbatim. This step cleans up leftover panes/debt from earlier scale-down operations before the team is torn down.

Solutions

  1. Inspect the reconciler's error message to identify the failing debt record and clean it up manually
  2. Ensure the tmux server/session is reachable, then retry shutdown
  3. As a last resort, clear stale scale-down debt records for the team and retry shutdown

Example fix

// before
await shutdownTeam(team, cwd);

// after
const res = await reconcileScaleDownCleanupDebt(team, cwd, config);
if (!res.ok) await clearScaleDownDebtRecords(team, cwd); // manual cleanup
await shutdownTeam(team, cwd);
Defensive patterns

Strategy: retry

Validate before calling

const res = await reconcileScaleDownCleanupDebt(teamName, cwd, config);
if (!res.ok) throw new Error(res.error);

Try / catch

try { await shutdownTeam(t, cwd); } catch (e) { if (/scale.?down/i.test((e as Error).message)) { await clearScaleDownDebtRecords(t, cwd); await shutdownTeam(t, cwd); } else throw e; }

Prevention

When it happens

Trigger: Running team shutdown while the scale-down cleanup reconciliation encounters an error — e.g. unreadable debt records, tmux failures, or inconsistent pane references recorded from previous scale-downs.

Common situations: Leftover scale-down state referencing panes that no longer exist; tmux server restarted so recorded pane IDs are invalid; partially-written cleanup-debt records after a crash.

Related errors


AI-assisted analysis of Yeachan-Heo/oh-my-codex@3ad79a8a6f (2026-08-27). Data as JSON: /api/errors/715256d67eb67da0. Report an issue: GitHub.

Appendix: source

Thrown at src/team/runtime.ts:4914

    } catch (error) {
      if (!(error instanceof Error) || !error.message.startsWith('restored_hud_cleanup_debt_unresolved:')) {
        throw error;
      }
      // The config identity is not the debt identity. Remove it durably before
      // replaying the pinned obligation: a later detached-session teardown must
      // not treat a live, same-PID/owner non-HUD pane as the restored HUD.
      config = await mutateShutdownConfig(config, cwd, (current) => {
        current.hud_pane_id = null;
        current.hud_pane_pid = undefined;
      });

      reconcileRestoredHudCleanupDebtSync(cwd, restoredHudDebtRoot);
    }
  } else {
    reconcileRestoredHudCleanupDebtSync(cwd, restoredHudDebtRoot);
  }
  const priorScaleDownCleanup = await reconcileScaleDownCleanupDebt(sanitized, cwd, config);
  if (!priorScaleDownCleanup.ok) throw new Error(priorScaleDownCleanup.error);
  await reconcileGonePaneDescendantCleanupDebt(sanitized, cwd, config);
  const manifest = await readTeamManifestV2(sanitized, cwd);
  const leaderSessionId = typeof manifest?.leader?.session_id === 'string'
    ? manifest.leader.session_id.trim()
    : '';
  const governance = resolveGovernancePolicy(
    manifest?.governance,
    manifest?.policy as Partial<TeamGovernance> | undefined,
  );

  const classification = await withTeamTaskMembershipBarrier(sanitized, cwd, async () => {
    const current = await classifyShutdown({
      teamName: sanitized,
      cwd,
      config: config!,
      governance,
      confirmIssues,
    });

View on GitHub (pinned to 3ad79a8a6f)