can1357/oh-my-pi · critical · Error

Failed to restore workspace after failed switch to ${newCwd}

Error message

Failed to restore workspace after failed switch to ${newCwd}: ${restoreError instanceof Error ? restoreError.message : String(restoreError)} (workspace may be inconsistent at ${actual})

What it means

When a cwd switch fails, InteractiveMode tries to restore the previous workspace; if that restore also fails, it throws this error because the session's working-directory state may now be inconsistent. The user-visible message is shown via showError and the error propagates so callers know state is unreliable.

Source

Thrown at packages/coding-agent/src/modes/interactive-mode.ts:1629

				await this.refreshSlashCommandState(previousCwd);
			} catch (restoreError) {
				const actual = this.sessionManager.getCwd();
				try {
					setProjectDir(actual);
					if (isSettingsInitialized()) {
						await settings.reloadForCwd(actual);
						applyProviderGlobalsFromSettings(settings);
					}
					clearClaudePluginRootsCache();
					await this.refreshTitleSystemPrompt(actual);
					resetCapabilities();
					await this.refreshSkillState();
					await this.refreshSlashCommandState(actual);
				} catch {}
				this.showError(
					`Failed to switch to ${newCwd} (${error instanceof Error ? error.message : String(error)}), and restoring the previous workspace failed: ${restoreError instanceof Error ? restoreError.message : String(restoreError)}`,
				);
				throw new Error(
					`Failed to restore workspace after failed switch to ${newCwd}: ${restoreError instanceof Error ? restoreError.message : String(restoreError)} (workspace may be inconsistent at ${actual})`,
				);
			}
			this.showError(
				`Cannot change working directory to ${newCwd}: ${error instanceof Error ? error.message : String(error)}`,
			);
			return false;
		}
		setSessionTerminalTitle(this.sessionManager.getSessionName(), this.sessionManager.getCwd());
		this.statusLine.applyCwdChange();
		return true;
	}

	async getUserInput(): Promise<SubmittedUserInput> {
		if (this.session.getGoalModeState()?.mode === "exiting") {
			await this.#exitGoalMode({ reason: "completed", silent: true });
		}
		const { promise, resolve } = Promise.withResolvers<SubmittedUserInput>();

View on GitHub (pinned to 9690622007)

Solutions

  1. Manually chdir/verify the process cwd (shown in the error as `actual`) and correct it — e.g. run /cd again to a valid directory or restart the session
  2. Check both newCwd and the original directory exist and are accessible (permissions, mount health)
  3. Look at the restoreError detail in the message to see which restore step (chdir vs refreshSkillState vs git workspace) failed
  4. As a last resort restart the coding-agent session to guarantee a consistent workspace state

Example fix

// before
await mode.changeDirectory(newCwd);
// after
try {
  await mode.changeDirectory(newCwd);
} catch (e) {
  if (String(e).includes("workspace may be inconsistent")) {
    await mode.changeDirectory(process.cwd()); // re-anchor to a known-good dir
  }
  throw e;
}
Defensive patterns

Strategy: try-catch

Validate before calling

for (const dir of [newCwd, originalCwd]) {
  await fs.access(dir, fs.constants.R_OK | fs.constants.X_OK); // both must be reachable
}

Try / catch

try {
  await mode.changeDirectory(newCwd);
} catch (err) {
  if (String(err).includes("workspace may be inconsistent")) {
    // state untrusted: re-anchor or restart session
    await mode.changeDirectory(process.cwd());
  }
  throw err;
}

Prevention

When it happens

Trigger: Calling the change-directory flow (e.g. /cd command) where the switch to newCwd throws, and the subsequent restore of the previous cwd (chdir back, re-init workspace, refresh skill/slash state) also throws — with `actual` being the cwd the process ended up in.

Common situations: Both the target directory and the original directory became inaccessible (network mount dropped, permissions changed, directory deleted); watcher or git-workspace re-init failing during rollback on a stale path.

Related errors


AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31). Data as JSON: /api/errors/78f25e2c586a8be2. Report an issue: GitHub.