{"record":{"id":"ebc725019081613c","repo":"google-gemini/gemini-cli","slug":"the-path-trimmedpath-is-not-a-directory","errorCode":null,"errorMessage":"The path \"${trimmedPath}\" is not a directory.","messagePattern":"The path \"(.+?)\" is not a directory\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/a2a-server/src/utils/path_utils.ts","lineNumber":52,"sourceCode":"    const resolvedWorkspacePath = path.resolve(\n      canonicalAllowedRoot,\n      trimmedPath,\n    );\n    const canonicalWorkspacePath = resolveToRealPath(resolvedWorkspacePath);\n\n    // Check if the resolved path is within the allowed root directory\n    if (\n      canonicalWorkspacePath !== canonicalAllowedRoot &&\n      !isSubpath(canonicalAllowedRoot, canonicalWorkspacePath)\n    ) {\n      throw new Error(\n        `Security violation: The path \"${trimmedPath}\" is outside the allowed root directory.`,\n      );\n    }\n\n    const stats = await fs.promises.stat(canonicalWorkspacePath);\n    if (!stats.isDirectory()) {\n      throw new Error(`The path \"${trimmedPath}\" is not a directory.`);\n    }\n\n    return canonicalWorkspacePath;\n  } catch (e) {\n    if (e instanceof Error && 'code' in e && e.code === 'ENOENT') {\n      throw new Error(`The path \"${trimmedPath}\" does not exist.`);\n    }\n    throw e; // Re-throw other errors\n  }\n}\n","sourceCodeStart":34,"sourceCodeEnd":63,"githubUrl":"https://github.com/google-gemini/gemini-cli/blob/5024443c7217464a66e98f80d73172a26440bd8f/packages/a2a-server/src/utils/path_utils.ts#L34-L63","documentation":"After confirming the resolved path is within the allowed root, the function stats it. If the path exists on disk but is not a directory (e.g., a regular file, socket, device node), it throws because a workspace path must resolve to a directory.","triggerScenarios":"Calling validateWorkspacePath('config.json') where config.json is a regular file within the root, or pointing to any non-directory filesystem entry.","commonSituations":"Pointing to a file instead of a folder; typo in the path resolving to an existing file; the intended directory was replaced by a file of the same name.","solutions":["Verify the path points to a directory, not a file.","Create the directory before validation if it should exist.","Correct the path to reference the intended folder."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"import * as fs from 'node:fs';\n\nasync function isDirectory(path: string): Promise<boolean> {\n  try {\n    const stats = await fs.promises.stat(path);\n    return stats.isDirectory();\n  } catch {\n    return false;\n  }\n}\n\n// Before calling validateWorkspacePath with a known absolute path:\nif (!(await isDirectory(resolvedPath))) {\n  throw new Error('Expected a directory but found a file or other type.');\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Verify paths point to directories, not files, before validation.","Use directory picker UI or autocomplete that only surfaces folders."],"tags":["validation","filesystem","workspace"],"backgroundTag":null,"analyzedSha":"5024443c7217464a66e98f80d73172a26440bd8f","analyzedAt":"2026-08-12T06:01:53.711Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}