ComposioHQ/composio · warning · FileUploadAbortedError

File upload was aborted because before_file_upload returned

Error message

File upload was aborted because before_file_upload returned False.

What it means

The SDK supports a before_file_upload hook. If the hook returns exactly False, the upload is deliberately cancelled and FileUploadAbortedError is raised — this is intentional user-configured rejection, not an infrastructure failure.

Source

Thrown at python/composio/core/models/_files.py:610

        :return: FileUploadable instance with S3 key
        """
        file_str = str(file) if isinstance(file, Path) else file
        path_in = file_str
        source: t.Literal["url", "path"] = (
            "url" if isinstance(file_str, str) and _is_url(file_str) else "path"
        )

        if before_file_upload is not None:
            out = before_file_upload(
                {
                    "path": path_in,
                    "source": source,
                    "tool": tool,
                    "toolkit": toolkit,
                }
            )
            if out is False:
                raise FileUploadAbortedError(
                    "File upload was aborted because before_file_upload returned False."
                )
            if isinstance(out, str):
                path_in = out

        # Re-decide routing on the post-hook value: a URL-source hook may return
        # a local path (and vice versa). Re-checking with `_is_url` keeps the
        # URL fetch path and the local-file path properly separated, so a hook
        # cannot, for example, smuggle `/etc/passwd` past the URL branch's
        # missing allowlist/denylist by rewriting the URL into a path.
        if isinstance(path_in, str) and _is_url(path_in):
            return cls.from_url(client=client, url=path_in, tool=tool, toolkit=toolkit)

        # Allowlist check runs BEFORE the denylist / existence checks when enabled,
        # so the "configure file_upload_dirs" hint fires first for the common case
        # (user has auto-upload on but hasn't configured dirs). Caller passes
        # ``None`` to bypass the allowlist (manual upload APIs).
        if file_upload_allowlist is not None:

View on GitHub (pinned to 64b1b85502)

Solutions

  1. If the rejection is unexpected, inspect your before_file_upload hook logic — it returned False; fix the condition or return the (possibly rewritten) path string instead.
  2. If rejection is intended, catch FileUploadAbortedError and handle it as a policy outcome, not an error.
  3. Make hook return types explicit: return path_in (str) to continue, False only to abort.

Example fix

# before
def hook(source, **ctx):
    return source.endswith('.pdf')  # returns False for .csv -> aborts
# after
def hook(source, **ctx):
    if not source.endswith('.pdf'):
        return source  # continue with original path
    return source
Defensive patterns

Strategy: try-catch

Validate before calling

# before registering the hook, assert its return contract on sample inputs
sample = 'notes.txt'
out = my_hook(source=sample, tool='t', toolkit='k')
assert out is False or isinstance(out, str), 'hook must return str or False'

Type guard

def hook_result_ok(out) -> bool:
    return out is False or isinstance(out, str)

Try / catch

from composio.core.models._files import FileUploadAbortedError

try:
    model = FileModel.from_path(client, path)
except FileUploadAbortedError:
    # policy rejection: log and skip, not a system error
    logger.info('upload rejected by before_file_upload hook')

Prevention

When it happens

Trigger: Registering a before_file_upload callback (on a tool/toolkit/model level) that returns False for a given file — e.g. policy checks rejecting file types, size, or paths — and then triggering an upload via from_path for such a file.

Common situations: Content-policy hooks rejecting executable/media types; size guard hooks; hooks that accidentally return False (e.g. returning falsy values like None→handled, but a bare `return condition` that evaluates False) instead of the path string.

Related errors


AI-assisted analysis of ComposioHQ/composio@64b1b85502 (2026-08-28). Data as JSON: /api/errors/e9b6ae18539dab55. Report an issue: GitHub.