{"record":{"id":"736cbb26349b8e1d","repo":"can1357/oh-my-pi","slug":"path-not-found-absolutepath","errorCode":null,"errorMessage":"Path not found: ${absolutePath}","messagePattern":"Path not found: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/coding-agent/src/extensibility/legacy-pi-coding-agent-shim.ts","lineNumber":633,"sourceCode":"\t\tlabel: \"find\",\n\t\tdescription: \"Find files by glob pattern.\",\n\t\tparameters: legacyFindSchema,\n\t\tapproval: \"read\",\n\t\trenderCall: (params, optionsArg, themeArg) => {\n\t\t\tconst theme = renderTheme(optionsArg, themeArg);\n\t\t\tconst pattern = stringField(params, \"pattern\") ?? \"\";\n\t\t\tconst searchPath = stringField(params, \"path\") ?? \".\";\n\t\t\treturn new Text(`${themedTitle(theme, \"find\")} ${themedMuted(theme, `${pattern} in ${searchPath}`)}`, 0, 0);\n\t\t},\n\t\trenderResult: legacyRenderResult,\n\t\texecute: async (toolCallId, params, signal, onUpdate) => {\n\t\t\tconst pattern = stringField(params, \"pattern\") ?? \"*\";\n\t\t\tconst searchPath = stringField(params, \"path\") ?? \".\";\n\t\t\tconst limit = normalizeLegacyLimit(numberField(params, \"limit\"), 1000);\n\t\t\tconst absolutePath = path.resolve(cwd, searchPath);\n\t\t\tif (options?.operations) {\n\t\t\t\tif (!(await options.operations.exists(absolutePath))) {\n\t\t\t\t\tthrow new Error(`Path not found: ${absolutePath}`);\n\t\t\t\t}\n\t\t\t\tconst matches = await options.operations.glob(pattern, absolutePath, {\n\t\t\t\t\tignore: [\"**/node_modules/**\", \"**/.git/**\"],\n\t\t\t\t\tlimit,\n\t\t\t\t});\n\t\t\t\tconst output = matches\n\t\t\t\t\t.map(match => {\n\t\t\t\t\t\tconst rel = path.isAbsolute(match) ? path.relative(absolutePath, match) : match;\n\t\t\t\t\t\treturn rel.split(path.sep).join(\"/\");\n\t\t\t\t\t})\n\t\t\t\t\t.join(\"\\n\");\n\t\t\t\tconst truncation = truncateHead(output, { maxLines: Number.MAX_SAFE_INTEGER });\n\t\t\t\treturn {\n\t\t\t\t\tcontent: [{ type: \"text\", text: truncation.content || \"No files found matching pattern\" }],\n\t\t\t\t\tdetails: truncation.truncated ? { truncation } : undefined,\n\t\t\t\t};\n\t\t\t}\n\t\t\treturn tool.execute(","sourceCodeStart":615,"sourceCodeEnd":651,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/coding-agent/src/extensibility/legacy-pi-coding-agent-shim.ts#L615-L651","documentation":"The legacy glob tool shim resolves the caller-supplied `path` parameter against the working directory and verifies it exists via the operations adapter before globbing. If `options.operations.exists(absolutePath)` returns false, it throws 'Path not found: <absolutePath>'. This guards the glob call against nonexistent roots.","triggerScenarios":"Calling the legacy glob tool (createGlobTool / shim read path) with a `path` param that resolves to a directory that does not exist on disk, or when the injected operations adapter's `exists()` reports false (e.g. a virtual/in-memory FS missing the entry).","commonSituations":"Relative path typo or wrong working directory assumption; tool invoked by an LLM agent hallucinating a path; path deleted between planning and execution; custom operations seam whose exists() implementation is broken or scoped to a sandbox root.","solutions":["Check the absolute path printed in the message and verify it exists (ls/stat it).","Fix the `path` parameter passed to the tool — use an absolute path or confirm the session cwd.","If using a custom operations adapter, ensure exists() correctly reflects the target filesystem.","Create the missing directory if it was expected to exist."],"exampleFix":"// before\nglob({ pattern: \"*.ts\", path: \"src/typo-dir\" })\n// after\nglob({ pattern: \"*.ts\", path: \"src\" })","handlingStrategy":"validation","validationCode":"import * as path from \"node:path\";\nimport * as fs from \"node:fs/promises\";\nconst absolutePath = path.resolve(cwd, searchPath);\nawait fs.access(absolutePath); // throws ENOENT early with your own message\n","typeGuard":"async function pathExists(p: string): Promise<boolean> {\n  try { await fs.stat(p); return true; } catch { return false; }\n}\nif (!(await pathExists(absolutePath))) throw new Error(`Skipping glob: ${absolutePath} does not exist`);","tryCatchPattern":"try {\n  await globTool.run({ pattern: \"*.ts\", path: \"src\" });\n} catch (err) {\n  if (err instanceof Error && err.message.startsWith(\"Path not found:\")) {\n    // fall back to cwd or surface a corrected path\n  } else throw err;\n}","preventionTips":["Always pass absolute paths to the legacy glob tool","Resolve relative paths against the cwd you actually run under","Check paths exist right before tool invocation to avoid TOCTOU surprises"],"tags":["filesystem","path-not-found","legacy-shim","tools"],"backgroundTag":"path-not-found","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}