{"record":{"id":"4b7e3ebba9572b61","repo":"transloadit/uppy","slug":"no-access-to-filepath-please-ensure-the-dire","errorCode":null,"errorMessage":"No access to \"${filePath}\". Please ensure the directory exists and with read/write permissions.","messagePattern":"No access to \"(.+?)\"\\. Please ensure the directory exists and with read/write permissions\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"critical","filePath":"packages/@uppy/companion/src/config/companion.ts","lineNumber":100,"sourceCode":"    .array()\n    .optional(),\n  maxFilenameLength: z.number().positive().optional(),\n})\n\n/**\n * Validates that the mandatory Companion options are set.\n *\n * If invalid, throws with an error explaining what needs to be fixed.\n */\nexport function validateConfig(companionOptions: CompanionInitOptions): void {\n  const parsedConfig = validateConfigSchema.parse(companionOptions)\n  const { filePath } = parsedConfig\n\n  // validate that specified filePath is writeable/readable.\n  try {\n    fs.accessSync(filePath, fs.constants.R_OK | fs.constants.W_OK)\n  } catch {\n    throw new Error(\n      `No access to \"${filePath}\". Please ensure the directory exists and with read/write permissions.`,\n    )\n  }\n\n  const { providerOptions, server, uploadUrls } = companionOptions\n\n  // see https://github.com/transloadit/uppy/issues/4271\n  // todo fix the code so we can allow `/`\n  if (server.path === '/') {\n    throw new Error(\n      \"If you want to use '/' as server.path, leave the 'path' variable unset\",\n    )\n  }\n\n  if (providerOptions) {\n    const deprecatedOptions: Record<string, string> = {\n      microsoft: 'providerOptions.onedrive',\n      google: 'providerOptions.drive',","sourceCodeStart":82,"sourceCodeEnd":118,"githubUrl":"https://github.com/transloadit/uppy/blob/5d4dedd02a1ac0ae022c75c54aca76558f88e256/packages/@uppy/companion/src/config/companion.ts#L82-L118","documentation":"Companion validates at startup that its filePath (the directory used for temporary downloads/uploads) exists and is readable and writable via fs.accessSync. If the OS denies access or the directory doesn't exist, validateConfig throws this error.","triggerScenarios":"Starting Companion with filePath pointing to a missing directory, a read-only volume, or a directory owned by another user (common in Docker where the container user differs from the volume owner).","commonSituations":"Docker/Kubernetes deployments with improperly permissioned volumes; filePath defaulting to /tmp on locked-down systems; running under a non-root service user.","solutions":["mkdir -p the directory and chown it to the user running Companion","Set filePath in companion config to an existing writable path","In Docker, ensure the mounted volume's ownership matches the container user (or use the proper USER directive)"],"exampleFix":"// before\ncompanionOptions.filePath = '/data/companion'\n\n// after (Dockerfile)\nRUN mkdir -p /data/companion && chown -R node:node /data/companion\nUSER node","handlingStrategy":"validation","validationCode":"import fs from 'node:fs'\nfs.accessSync(filePath, fs.constants.R_OK | fs.constants.W_OK)","typeGuard":"null","tryCatchPattern":"try { companion.app(options) } catch (e) { if (String(e?.message).includes('No access to')) { fixPermissions(); } throw e }","preventionTips":["Pre-create and chown the data directory in Dockerfiles","Health-check volume permissions in deployment scripts","Run Companion under a dedicated user that owns filePath"],"tags":["companion","filesystem","permissions","startup","docker"],"backgroundTag":"permission-denied-directory","analyzedSha":"5d4dedd02a1ac0ae022c75c54aca76558f88e256","analyzedAt":"2026-08-28T12:18:41.267Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}