{"record":{"id":"865cdc54dd177532","repo":"ComposioHQ/composio","slug":"refusing-to-auto-upload-attempted-no-upload","errorCode":null,"errorMessage":"Refusing to auto-upload \"${attempted}\": no upload directories are configured.\n\nPath attempted:   ${attempted}\nResolved to:      ${real}\n\nAutomatic file upload during tool execution is locked down by default\nto prevent a prompt-injected tool from exfiltrating server files\n(source code, .env, SSH keys, etc.).\n${buildHelpFooter(allowlist)}","messagePattern":"Refusing to auto-upload \"(.+?)\": no upload directories are configured\\.\n\nPath attempted:   (.+?)\nResolved to:      (.+?)\n\nAutomatic file upload during tool execution is locked down by default\nto prevent a prompt-injected tool from exfiltrating server files\n\\(source code, \\.env, SSH keys, etc\\.\\)\\.\n(.+?)","errorType":"exception","errorClass":"ComposioFileUploadPathNotAllowedError","httpStatus":null,"severity":"error","filePath":"ts/packages/core/src/utils/uploadDirAllowlist.node.ts","lineNumber":144,"sourceCode":"        `Path attempted:   ${attempted}`,\n        `Resolved to:      ${abs}`,\n        `Process cwd:      ${cwd}`,\n        `Parent exists:    ${parentExists ? 'yes (' + parent + ')' : 'no (' + parent + ')'}`,\n        '',\n        'Common causes:',\n        '  - Typo in the filename passed to the tool.',\n        '  - Relative path resolved against the wrong working directory',\n        '    (relative paths use process.cwd() at the moment of upload).',\n        '  - File was deleted between the tool being called and the upload starting.',\n        '',\n        buildHelpFooter(allowlist),\n      ].join('\\n'),\n      { meta: { attempted, resolved: abs, cwd, allowlist } }\n    );\n  }\n\n  if (allowlist.length === 0) {\n    throw new ComposioFileUploadPathNotAllowedError(\n      [\n        `Refusing to auto-upload \"${attempted}\": no upload directories are configured.`,\n        '',\n        `Path attempted:   ${attempted}`,\n        `Resolved to:      ${real}`,\n        '',\n        'Automatic file upload during tool execution is locked down by default',\n        'to prevent a prompt-injected tool from exfiltrating server files',\n        '(source code, .env, SSH keys, etc.).',\n        buildHelpFooter(allowlist),\n      ].join('\\n'),\n      { meta: { attempted, resolved: real, allowlist } }\n    );\n  }\n\n  for (const dir of allowlist) {\n    const realDir = tryRealpath(dir) ?? path.resolve(dir);\n    if (isInsideDir(real, realDir)) {","sourceCodeStart":126,"sourceCodeEnd":162,"githubUrl":"https://github.com/ComposioHQ/composio/blob/64b1b85502b1beeb2379e6c9e8bf1104504fa637/ts/packages/core/src/utils/uploadDirAllowlist.node.ts#L126-L162","documentation":"assertPathInsideUploadDirs throws ComposioFileUploadPathNotAllowedError when automatic file upload is attempted but the fileUploadDirs allowlist is empty. Auto-upload is locked down by default so a prompt-injected tool cannot exfiltrate server files (.env, source, SSH keys).","triggerScenarios":"A tool execution with a local file argument triggers getFileDataAfterUploadingToS3 while no fileUploadDirs directories are configured on the Composio client.","commonSituations":"First-time use of file-uploading tools in server environments; adding file tools to an agent without configuring the allowlist; upgrading to an SDK version that introduced the allowlist default.","solutions":["Configure fileUploadDirs in the Composio client config with the specific directories that should be uploadable (e.g. [os.tmpdir(), './uploads'])","Keep the allowlist narrow — only dedicated upload/scratch dirs, never project root or home","Alternatively disable auto-upload expectations by passing remote URLs to the tool instead of local paths"],"exampleFix":"// before\nconst composio = new Composio({ apiKey });\n// after\nconst composio = new Composio({ apiKey, fileUploadDirs: [path.resolve('./uploads'), os.tmpdir()] });","handlingStrategy":"validation","validationCode":"const cfg = composio.getConfig?.() ?? {};\n// Or at construction: ensure fileUploadDirs is set if any tool takes file args","typeGuard":null,"tryCatchPattern":"catch (e) { if (e instanceof ComposioFileUploadPathNotAllowedError && /no upload directories/.test(e.message)) { /* instruct: configure fileUploadDirs or pass remote URL */ } throw e; }","preventionTips":["Configure fileUploadDirs at client construction when using file tools","Keep the allowlist to dedicated upload directories","Prefer passing hosted URLs for files instead of local paths"],"tags":["file-upload","security","allowlist","configuration"],"backgroundTag":"file-upload-not-allowed","analyzedSha":"64b1b85502b1beeb2379e6c9e8bf1104504fa637","analyzedAt":"2026-08-28T15:39:33.623Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}