ComposioHQ/composio · error · ErrorUploadingFile

Failed to fetch file from URL: {_sanitize_url_for_logging(ur

Error message

Failed to fetch file from URL: {_sanitize_url_for_logging(url)}. Status: {response.status_code}

What it means

MCPServer.create was called with an empty or falsy toolkits argument. At least one toolkit configuration (string slug or MCPToolkitConfig) is required to create an MCP server.

Source

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

        )
    except requests.exceptions.RequestException as e:
        raise ErrorUploadingFile(
            f"Failed to fetch file from URL: {_sanitize_url_for_logging(url)}. Error: {e}"
        )

    # Reject redirects - require direct URL to resource
    if response.status_code in (301, 302, 303, 307, 308):
        location = response.headers.get("Location", "unknown")
        response.close()
        raise ErrorUploadingFile(
            f"URL returned redirect to {_sanitize_url_for_logging(location)}. "
            f"Please provide a direct URL to the file."
        )

    # Check for successful response
    if not response.ok:
        response.close()
        raise ErrorUploadingFile(
            f"Failed to fetch file from URL: {_sanitize_url_for_logging(url)}. "
            f"Status: {response.status_code}"
        )

    # Check Content-Length header first (early abort for oversized files).
    # The header is a hint from the remote server: `parse_content_length`
    # returns None for anything untrustworthy, and the streaming guard below
    # is the authoritative limit.
    content_length = parse_content_length(response.headers.get("Content-Length"))
    if content_length is not None and content_length > max_size:
        response.close()
        raise ResponseTooLargeError(
            f"File size ({content_length} bytes) exceeds maximum allowed "
            f"size ({max_size} bytes)"
        )

    # Stream response with size tracking
    chunks: t.List[bytes] = []

View on GitHub (pinned to 64b1b85502)

Solutions

  1. Pass at least one toolkit slug or MCPToolkitConfig (e.g. ['github'])
  2. Guard before calling: skip server creation when the toolkit list is empty
  3. Fix upstream logic that produces an empty toolkits collection

Example fix

# before
mcp = server.create(toolkits=filtered_toolkits)  # may be []
# after
if filtered_toolkits:
    mcp = server.create(toolkits=filtered_toolkits)
else:
    raise ValueError('No toolkits selected for MCP server')
Defensive patterns

Strategy: validation

Validate before calling

if not toolkits:
    raise ValueError('Cannot create MCP server with no toolkits')
mcp = server.create(toolkits=toolkits)

Type guard

def has_toolkits(toolkits) -> bool:
    return bool(toolkits) and len(list(toolkits)) > 0

Try / catch

try:
    mcp = server.create(toolkits=toolkits)
except ValidationError as e:
    if str(e) == 'At least one toolkit configuration is required':
        raise ValueError(f'Build toolkits list before creating MCP server') from e
    raise

Prevention

When it happens

Trigger: Calling server.create(toolkits=[]), server.create(toolkits=None), or passing an empty list/iterable to MCPServer.create in python/composio/core/models/mcp.py.

Common situations: Dynamically building the toolkit list and passing an empty result; conditionally filtering toolkits down to nothing; defaulting a config value to an empty list.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


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