{"record":{"id":"c5ba371ae7f95dfc","repo":"ComposioHQ/composio","slug":"file-upload-was-aborted-because-beforefileupload-r","errorCode":null,"errorMessage":"File upload was aborted because beforeFileUpload returned false.","messagePattern":"File upload was aborted because beforeFileUpload returned false\\.","errorType":"exception","errorClass":"ComposioFileUploadAbortedError","httpStatus":null,"severity":"warning","filePath":"ts/packages/core/src/utils/modifiers/FileToolModifier.node.ts","lineNumber":91,"sourceCode":"  if (isEmptyFileValue(value)) return DELETE_VALUE;\n  // Upload only if the runtime value is a string (i.e., a local path) or blob\n  if (typeof value !== 'string' && !(value instanceof File)) return value;\n\n  const runBeforeFileUpload = async (\n    path: string,\n    source: 'path' | 'url' | 'file'\n  ): Promise<string> => {\n    if (!ctx.beforeFileUpload) {\n      return path;\n    }\n    const out = await ctx.beforeFileUpload({\n      path,\n      source,\n      toolSlug: ctx.toolSlug,\n      toolkitSlug: ctx.toolkitSlug,\n    });\n    if (out === false) {\n      throw new ComposioFileUploadAbortedError(\n        'File upload was aborted because beforeFileUpload returned false.'\n      );\n    }\n    return out;\n  };\n\n  if (typeof value === 'string') {\n    // Match the URL/local-path split used downstream in\n    // getFileDataAfterUploadingToS3 so the hook sees the same categorisation.\n    const source = isHttpUrl(value) ? 'url' : 'path';\n    const pathOrUrl = await runBeforeFileUpload(value, source);\n    logger.debug(`Uploading file \"${pathOrUrl}\"`);\n    return getFileDataAfterUploadingToS3(pathOrUrl, {\n      toolSlug: ctx.toolSlug,\n      toolkitSlug: ctx.toolkitSlug,\n      client: ctx.client,\n      sensitiveFileUploadProtection: ctx.sensitiveFileUploadProtection,\n      fileUploadPathDenySegments: ctx.fileUploadPathDenySegments,","sourceCodeStart":73,"sourceCodeEnd":109,"githubUrl":"https://github.com/ComposioHQ/composio/blob/64b1b85502b1beeb2379e6c9e8bf1104504fa637/ts/packages/core/src/utils/modifiers/FileToolModifier.node.ts#L73-L109","documentation":"runBeforeFileUpload invokes the user-supplied beforeFileUpload hook; when the hook returns false, the SDK aborts the upload with ComposioFileUploadAbortedError. This is a deliberate, policy-driven abort for local paths/URLs.","triggerScenarios":"Configuring a FileToolModifier with beforeFileUpload that returns false for a given path/url (e.g. allowlist mismatch, size check failed) and then executing the tool with that path.","commonSituations":"Allowlisting specific directories, blocking file types, or content checks in the hook — the throw is your own policy firing, not a bug.","solutions":["This is expected behavior: catch ComposioFileUploadAbortedError and handle the rejection gracefully.","Adjust the hook's condition if legitimate files are being rejected.","Log path/source in the hook to see why it returned false."],"exampleFix":"// before\nbeforeFileUpload: ({ path }) => path.startsWith('/data'),\n// after\nbeforeFileUpload: ({ path }) => path.startsWith('/data') || path.startsWith('/tmp/uploads'),","handlingStrategy":"try-catch","validationCode":null,"typeGuard":"const isUploadAborted = (e: unknown): e is ComposioFileUploadAbortedError =>\n  e instanceof ComposioFileUploadAbortedError;","tryCatchPattern":"try { await tool.execute(args); }\ncatch (e) { if (isUploadAborted(e)) { /* policy rejection, skip */ return; } throw e; }","preventionTips":["Make beforeFileUpload conditions explicit and logged.","Return true for allowed files; return false only for intentional blocks."],"tags":["file-upload","modifier","hook","typescript"],"backgroundTag":"upload-rejected-by-policy","analyzedSha":"64b1b85502b1beeb2379e6c9e8bf1104504fa637","analyzedAt":"2026-08-28T15:39:33.623Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}