ComposioHQ/composio · error · ToolFileUploadError
Unsupported upload source
Error message
Unsupported upload source
What it means
readUploadSource dispatches on the file argument's shape: Blob/File-like sources and plain strings (disk paths) are supported; anything else hits the terminal branch throwing ToolFileUploadError with reason 'unsupported-source'.
Source
Thrown at ts/packages/cli/src/services/tool-file-uploads.ts:226
file: string | File
) => {
if (isFileLike(file)) {
return {
bytes: new Uint8Array(await file.arrayBuffer()),
fileName: file.name || `file-${Date.now()}`,
mimeType: file.type || 'application/octet-stream',
};
}
if (typeof file === 'string' && /^https?:\/\//i.test(file)) {
return readFileFromUrl(path, file);
}
if (typeof file === 'string') {
return readFileFromDisk(fs, path, file);
}
throw new ToolFileUploadError({
message: 'Unsupported upload source',
reason: 'unsupported-source',
});
};
const uploadFile = async (params: {
readonly fs: FileSystem.FileSystem;
readonly path: Path.Path;
readonly file: string | File;
readonly toolSlug: string;
readonly toolkitSlug: string;
readonly client: RawComposioClient;
}) => {
const fileData = await readUploadSource(params.fs, params.path, params.file);
// eslint-disable-next-line no-restricted-imports -- MD5 for the presigned-upload checksum is not available in Web Crypto
const { createHash } = await import('node:crypto');
const md5 = createHash('md5').update(fileData.bytes).digest('hex');
const presigned = await params.client.files.createPresignedURL({View on GitHub (pinned to 64b1b85502)
Solutions
- Pass the local file path as a plain string
- Pass an actual Blob/File instance (e.g. new Blob([bytes])) — wrap Node Buffers: new Blob([buffer])
- Do not wrap the source in an object; unwrap { path } to path
Example fix
// before
upload({ file: { path: '/tmp/a.pdf' } });
// after
upload({ file: '/tmp/a.pdf' });
// or
upload({ file: new Blob([fs.readFileSync('/tmp/a.pdf')]) }); Defensive patterns
Strategy: type-guard
Validate before calling
if (typeof file !== 'string' && !(file instanceof Blob)) throw new TypeError('file must be a path string or Blob'); Type guard
const isUploadSource = (v: unknown): v is string | Blob => typeof v === 'string' || (typeof Blob !== 'undefined' && v instanceof Blob);
Prevention
- Never wrap paths in objects
- Convert Buffers: new Blob([buffer], { type })
- Type the upload parameter as string | Blob at the call site
When it happens
Trigger: Passing a file argument that is neither a Blob/File nor a string — e.g. a number, a plain object like { path: '...' }, a Buffer in an environment where it isn't recognized as a Blob, or null/undefined where a value is required.
Common situations: Wrapping the path in an object ({ path }) instead of passing the string, passing a Node Buffer where a Blob is expected, or a serialization step turning the File into a plain object.
Related errors
- Invalid file type
- Either path or blob must be provided
- maxBytes must be a non-negative safe integer
- Could not determine a home directory to store the Composio c
- Cache directory {directory} is not writable please provide a
AI-assisted analysis of ComposioHQ/composio@64b1b85502 (2026-08-28).
Data as JSON: /api/errors/4c0be6d10b07a6f0.
Report an issue: GitHub.