can1357/oh-my-pi · warning · Error

The current working directory is already the primary workspa

Error message

The current working directory is already the primary workspace root.

What it means

addWorkspaceDirectory() normalizes the requested directory and throws if it equals the session's current working directory, which is always the primary workspace root implicitly. Adding it again would be a meaningless duplicate; the API returns null (no-op) for directories already in the additional list, but the CWD itself is rejected outright.

Source

Thrown at packages/coding-agent/src/session/session-manager.ts:1976

	 * change in memory (the header lands with the first real write), so seeding
	 * roots at launch never materializes an empty resumable session file.
	 */
	async #persistWorkspaceDirectoriesChange(): Promise<void> {
		if (!this.#persist || !this.#sessionFile || !this.#shouldHaveSessionFile()) return;
		this.#rewriteRequired = true;
		await this.#rewriteAtomically();
	}

	/**
	 * Add a workspace directory. Normalizes (relative to cwd), dedupes, rejects
	 * the cwd itself, persists to the session header, and triggers an atomic
	 * rewrite so the change survives a crash. Returns the resolved absolute
	 * path or `null` when the directory was already present (no-op).
	 */
	async addWorkspaceDirectory(directory: string): Promise<string | null> {
		const resolved = normalizeWorkspaceDirectory(directory, this.#cwd);
		if (resolved === path.resolve(this.#cwd)) {
			throw new Error("The current working directory is already the primary workspace root.");
		}
		if (this.#additionalDirectories.includes(resolved)) return null;
		this.#additionalDirectories = [...this.#additionalDirectories, resolved];
		// In fallback the transcript is still in the stale bucket; keep
		// workspace edits runtime-only until relocation.
		if (this.#fallbackRuntimeOnly) {
			return resolved;
		}
		this.#header.additionalDirectories = this.#additionalDirectories;
		await this.#persistWorkspaceDirectoriesChange();
		return resolved;
	}

	/**
	 * Remove a workspace directory by absolute or cwd-relative path. Persists
	 * the trimmed header. Returns the resolved path that was removed, or
	 * `null` when the directory was not an additional root (no-op).
	 */

View on GitHub (pinned to 9690622007)

Solutions

  1. Skip the CWD before calling: only pass directories different from path.resolve(cwd).
  2. Normalize the candidate (path.resolve) and compare to the CWD in your own code to handle it gracefully.
  3. If you wanted the primary root included, do nothing — it is already a workspace root.

Example fix

// before
await mgr.addWorkspaceDirectory(process.cwd()); // throws
// after
const dir = path.resolve(candidate);
if (dir !== path.resolve(mgr.getCwd())) {
  await mgr.addWorkspaceDirectory(dir);
}
Defensive patterns

Strategy: validation

Validate before calling

const dir = path.resolve(candidate);
if (dir === path.resolve(mgr.getCwd())) {
  return; // already primary root — skip
}

Type guard

function isAdditionalDir(candidate, cwd) {
  return path.resolve(candidate) !== path.resolve(cwd);
}

Try / catch

try {
  await mgr.addWorkspaceDirectory(candidate);
} catch (err) {
  if (err.message.includes("already the primary workspace root")) {
    // no-op: primary root is implicit
  } else throw err;
}

Prevention

When it happens

Trigger: Calling SessionManager.addWorkspaceDirectory(cwd) — passing the session's current working directory (after path normalization, e.g. resolving . , symlinks, or a trailing slash) instead of a genuinely additional directory.

Common situations: Scripting bulk workspace setup from a config where one entry is '.' or the project root itself; passing an unnormalized path that resolves to the CWD; UI passing the active folder as a workspace.

Related errors


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