{"record":{"id":"f0886794183fb6b1","repo":"Mintplex-Labs/anything-llm","slug":"parent-directory-does-not-exist-parentdir","errorCode":null,"errorMessage":"Parent directory does not exist: ${parentDir}","messagePattern":"Parent directory does not exist: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"server/utils/agents/aibitat/plugins/filesystem/lib.js","lineNumber":470,"sourceCode":"        try {\n          const realParentPath = await fs.realpath(parentDir);\n          const normalizedParent = this.#normalizePath(realParentPath);\n          if (\n            !this.#isPathWithinAllowedDirectories(\n              normalizedParent,\n              this.#allowedDirectories\n            )\n          ) {\n            console.log(\n              `[validatePath] Access denied - parent directory outside allowed directories: ${realParentPath} not in ${this.#allowedDirectories.join(\", \")}`\n            );\n            throw new Error(\n              `Access denied - parent directory outside allowed directories.`\n            );\n          }\n          return absolute;\n        } catch {\n          throw new Error(`Parent directory does not exist: ${parentDir}`);\n        }\n      }\n      throw error;\n    }\n  }\n\n  /**\n   * Gets detailed file statistics.\n   * @param {string} filePath - Path to the file\n   * @returns {Promise<Object>} File statistics\n   */\n  async getFileStats(filePath) {\n    const stats = await fs.stat(filePath);\n    return {\n      size: stats.size,\n      sizeFormatted: humanFileSize(stats.size, true, 2),\n      created: stats.birthtime.toISOString(),\n      modified: stats.mtime.toISOString(),","sourceCodeStart":452,"sourceCodeEnd":488,"githubUrl":"https://github.com/Mintplex-Labs/anything-llm/blob/3aec848f2885144aa8f1e53b9731a04310d5d558/server/utils/agents/aibitat/plugins/filesystem/lib.js#L452-L488","documentation":"Thrown by validatePath when the target file does not exist and fs.realpath of its parent directory also fails — meaning the parent directory itself is missing. Any catch inside that inner try (not just ENOENT, e.g. ENOTDIR when a path component is a file, or permission errors) collapses into this single message. It typically surfaces from write/create calls that target a directory chain that was never created.","triggerScenarios":"write_file({ path: \"docs/2026/report.md\" }) when docs/2026/ does not exist anywhere under the allowed root; a path component is actually a regular file (docs is a file, so realpath of docs/ fails with ENOTDIR); intermediate directory deleted between a list_directory call and the write.","commonSituations":"Agent assumes nested folders exist and writes directly; user expects mkdir -p semantics from write_file; path typo creates a nonexistent chain like storage-dir/Documnets/file.txt.","solutions":["Create the directory chain first with the create_directory tool (or fs.mkdir with recursive: true), then retry the write.","Verify the exact chain with list_directory and correct typos in path components.","Check that no intermediate component is a file rather than a directory (ENOTDIR masquerades as this error)."],"exampleFix":"// before\nwrite_file({ path: \"docs/2026/report.md\", content })\n// -> Error: Parent directory does not exist: .../docs/2026\n\n// after\ncreate_directory({ path: \"docs/2026\" });\nwrite_file({ path: \"docs/2026/report.md\", content });","handlingStrategy":"validation","validationCode":"const fs = require(\"fs\").promises;\nconst path = require(\"path\");\nasync function ensureParentDir(target) {\n  const parent = path.dirname(path.resolve(target));\n  const st = await fs.stat(parent).catch(() => null);\n  if (!st?.isDirectory()) await fs.mkdir(parent, { recursive: true });\n}\nawait ensureParentDir(target); // now safe to write","typeGuard":null,"tryCatchPattern":"try {\n  await fileOps.writeFileContent(p, content);\n} catch (e) {\n  if (e.message.startsWith(\"Parent directory does not exist\")) {\n    await fs.mkdir(path.dirname(p), { recursive: true });\n    await fileOps.writeFileContent(p, content); // one retry after creating the chain\n  } else throw e;\n}","preventionTips":["Instruct agents to create_directory before write_file into new nested paths.","Wrap file-creation flows with an ensureParentDir helper using mkdir recursive.","Watch for typos in path components — they create phantom directories or hit this error."],"tags":["filesystem","missing-directory","file-creation","agent-tools"],"backgroundTag":"missing-parent-directory","analyzedSha":"3aec848f2885144aa8f1e53b9731a04310d5d558","analyzedAt":"2026-08-18T10:02:21.017Z","contentChangedAt":"2026-08-18T10:02:21.017Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}