{"record":{"id":"8a10f10d430b2512","repo":"Mintplex-Labs/anything-llm","slug":"access-denied-parent-directory-outside-allowed-d","errorCode":null,"errorMessage":"Access denied - parent directory outside allowed directories.","messagePattern":"Access denied - parent directory outside allowed directories\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"server/utils/agents/aibitat/plugins/filesystem/lib.js","lineNumber":464,"sourceCode":"        );\n      }\n      return realPath;\n    } catch (error) {\n      if (error.code === \"ENOENT\") {\n        const parentDir = path.dirname(absolute);\n        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) {","sourceCodeStart":446,"sourceCodeEnd":482,"githubUrl":"https://github.com/Mintplex-Labs/anything-llm/blob/526360e320da9d1b36074be5ed64fe76e5bbfbbd/server/utils/agents/aibitat/plugins/filesystem/lib.js#L446-L482","documentation":"Thrown by validatePath() in the ENOENT branch: the requested file does not yet exist, so realpath cannot resolve it. The code instead resolves the parent directory with realpath; if that real parent path is outside the allowed directories, this error fires. It prevents creating new files in locations that escape the sandbox via a symlinked parent.","triggerScenarios":"Writing/creating a file whose path does not exist yet, and whose parent directory (resolved to its real target via realpath) lies outside the allowed directories. Typical when the parent is a symlink pointing outside the workspace.","commonSituations":"Creating a file inside a symlinked directory that points outside the workspace; a nested path where an intermediate directory is an escaping symlink.","solutions":["Ensure the target parent directory genuinely exists inside an allowed directory (not via an escaping symlink).","Create the file in a direct subdirectory of the workspace.","Remove or fix symlinked parent directories before writing into them."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"const fs = require(\"fs/promises\");\nasync function assertParentInside(p, allowedDirs) {\n  const parent = path.dirname(path.resolve(p));\n  try {\n    const real = await fs.realpath(parent);\n    if (!allowedDirs.some((d) => real.startsWith(path.resolve(d))))\n      throw new Error(`Parent ${parent} resolves outside workspace`);\n  } catch { throw new Error(`Parent ${parent} does not exist`); }\n}","typeGuard":null,"tryCatchPattern":"try { await filesystem.validatePath(p); }\ncatch (e) {\n  if (e.message.includes(\"parent directory outside\")) { /* write inside a real workspace dir */ }\n  else throw e;\n}","preventionTips":["Write new files into directories that genuinely exist inside the workspace.","Avoid creating files under symlinked directories whose targets escape the sandbox.","Validate the parent directory's realpath before writing."],"tags":["filesystem","security","sandbox","symlink","path-validation"],"backgroundTag":null,"analyzedSha":"526360e320da9d1b36074be5ed64fe76e5bbfbbd","analyzedAt":"2026-08-13T01:45:47.170Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}