crewAIInc/crewAI · error · ValueError

Invalid URL scheme: {self.url}

Error message

Invalid URL scheme: {self.url}

What it means

Validation error from FileUrl's model_validator: the url field does not start with 'http://' or 'https://'. The check is a simple prefix test, so any other scheme — ftp://, file://, s3://, gs:// — or a scheme-less string like 'example.com/file.pdf' is rejected. FileUrl can only fetch over HTTP(S).

Source

Thrown at lib/crewai-files/src/crewai_files/core/sources.py:509

    For providers that support URL references, the URL is passed directly.
    For providers that don't, content is fetched on demand.

    Attributes:
        url: URL where the file can be accessed.
        filename: Optional filename (extracted from URL if not provided).
    """

    url: str = Field(description="URL where the file can be accessed.")
    filename: str | None = Field(default=None, description="Optional filename.")
    _content_type: str | None = PrivateAttr(default=None)
    _content: bytes | None = PrivateAttr(default=None)

    @model_validator(mode="after")
    def _validate_url(self) -> FileUrl:
        """Validate URL format."""
        if not self.url.startswith(("http://", "https://")):
            raise ValueError(f"Invalid URL scheme: {self.url}")
        return self

    @property
    def content_type(self) -> str:
        """Get the content type, guessing from URL extension if not set."""
        if self._content_type is None:
            self._content_type = self._guess_content_type()
        return self._content_type

    def _guess_content_type(self) -> str:
        """Guess content type from URL extension."""
        from urllib.parse import urlparse

        parsed = urlparse(self.url)
        path = parsed.path
        guessed, _ = mimetypes.guess_type(path)
        return guessed or "application/octet-stream"

View on GitHub (pinned to 754d7323be)

Solutions

  1. Use an http(s) URL: download a presigned URL for cloud objects (S3/GCS) instead of the native URI.
  2. Prepend 'https://' when the scheme is missing but the host is known.
  3. For local files use FilePath instead of a file:// URL.

Example fix

# before
src = FileUrl(url="s3://bucket/report.pdf")

# after
src = FileUrl(url="https://bucket.s3.amazonaws.com/report.pdf?X-Amz-...")
Defensive patterns

Strategy: type-guard

Validate before calling

def is_http_url(u: str) -> bool:
    return u.startswith(("http://", "https://"))

Type guard

def as_url_source(u: str):
    if u.startswith(("http://", "https://")):
        return FileUrl(url=u)
    if u.startswith(("s3://", "gs://")):
        raise TypeError("presign cloud URLs to https before use")
    return FilePath(path=Path(u))  # local path

Try / catch

try:
    FileUrl(url=value)
except ValidationError as e:
    if "Invalid URL scheme" in str(e):
        FileUrl(url="https://" + value.lstrip("/"))  # only when value is a bare host/path

Prevention

When it happens

Trigger: FileUrl(url="ftp://files.example.com/x.csv"), FileUrl(url="s3://bucket/key.pdf"), or FileUrl(url="example.com/file.pdf") without the scheme; also mixed-case 'HTTPS://' fails the case-sensitive check.

Common situations: Cloud-storage URIs pasted directly; user input missing the protocol; URLs normalized to lowercase-host but uppercase scheme; pretrained-pipeline configs referencing file:// paths.

Related errors


AI-assisted analysis of crewAIInc/crewAI@754d7323be (2026-08-15). Data as JSON: /api/errors/a9aa52073956b8a7. Report an issue: GitHub.