{"record":{"id":"da648d29e4b217c3","repo":"can1357/oh-my-pi","slug":"the-current-working-directory-is-already-the-prima","errorCode":null,"errorMessage":"The current working directory is already the primary workspace root.","messagePattern":"The current working directory is already the primary workspace root\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"warning","filePath":"packages/coding-agent/src/session/session-manager.ts","lineNumber":1976,"sourceCode":"\t * change in memory (the header lands with the first real write), so seeding\n\t * roots at launch never materializes an empty resumable session file.\n\t */\n\tasync #persistWorkspaceDirectoriesChange(): Promise<void> {\n\t\tif (!this.#persist || !this.#sessionFile || !this.#shouldHaveSessionFile()) return;\n\t\tthis.#rewriteRequired = true;\n\t\tawait this.#rewriteAtomically();\n\t}\n\n\t/**\n\t * Add a workspace directory. Normalizes (relative to cwd), dedupes, rejects\n\t * the cwd itself, persists to the session header, and triggers an atomic\n\t * rewrite so the change survives a crash. Returns the resolved absolute\n\t * path or `null` when the directory was already present (no-op).\n\t */\n\tasync addWorkspaceDirectory(directory: string): Promise<string | null> {\n\t\tconst resolved = normalizeWorkspaceDirectory(directory, this.#cwd);\n\t\tif (resolved === path.resolve(this.#cwd)) {\n\t\t\tthrow new Error(\"The current working directory is already the primary workspace root.\");\n\t\t}\n\t\tif (this.#additionalDirectories.includes(resolved)) return null;\n\t\tthis.#additionalDirectories = [...this.#additionalDirectories, resolved];\n\t\t// In fallback the transcript is still in the stale bucket; keep\n\t\t// workspace edits runtime-only until relocation.\n\t\tif (this.#fallbackRuntimeOnly) {\n\t\t\treturn resolved;\n\t\t}\n\t\tthis.#header.additionalDirectories = this.#additionalDirectories;\n\t\tawait this.#persistWorkspaceDirectoriesChange();\n\t\treturn resolved;\n\t}\n\n\t/**\n\t * Remove a workspace directory by absolute or cwd-relative path. Persists\n\t * the trimmed header. Returns the resolved path that was removed, or\n\t * `null` when the directory was not an additional root (no-op).\n\t */","sourceCodeStart":1958,"sourceCodeEnd":1994,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/coding-agent/src/session/session-manager.ts#L1958-L1994","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Skip the CWD before calling: only pass directories different from path.resolve(cwd).","Normalize the candidate (path.resolve) and compare to the CWD in your own code to handle it gracefully.","If you wanted the primary root included, do nothing — it is already a workspace root."],"exampleFix":"// before\nawait mgr.addWorkspaceDirectory(process.cwd()); // throws\n// after\nconst dir = path.resolve(candidate);\nif (dir !== path.resolve(mgr.getCwd())) {\n  await mgr.addWorkspaceDirectory(dir);\n}","handlingStrategy":"validation","validationCode":"const dir = path.resolve(candidate);\nif (dir === path.resolve(mgr.getCwd())) {\n  return; // already primary root — skip\n}","typeGuard":"function isAdditionalDir(candidate, cwd) {\n  return path.resolve(candidate) !== path.resolve(cwd);\n}","tryCatchPattern":"try {\n  await mgr.addWorkspaceDirectory(candidate);\n} catch (err) {\n  if (err.message.includes(\"already the primary workspace root\")) {\n    // no-op: primary root is implicit\n  } else throw err;\n}","preventionTips":["Normalize (path.resolve) candidates and compare to the CWD before adding.","Filter '.'/'..' style entries out of workspace config lists.","Remember the CWD is always included — only pass truly additional directories."],"tags":["session","workspace","validation"],"backgroundTag":"duplicate-workspace-root","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}