{"record":{"id":"a9aa52073956b8a7","repo":"crewAIInc/crewAI","slug":"invalid-url-scheme-self-url","errorCode":null,"errorMessage":"Invalid URL scheme: {self.url}","messagePattern":"Invalid URL scheme: (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"lib/crewai-files/src/crewai_files/core/sources.py","lineNumber":509,"sourceCode":"\n    For providers that support URL references, the URL is passed directly.\n    For providers that don't, content is fetched on demand.\n\n    Attributes:\n        url: URL where the file can be accessed.\n        filename: Optional filename (extracted from URL if not provided).\n    \"\"\"\n\n    url: str = Field(description=\"URL where the file can be accessed.\")\n    filename: str | None = Field(default=None, description=\"Optional filename.\")\n    _content_type: str | None = PrivateAttr(default=None)\n    _content: bytes | None = PrivateAttr(default=None)\n\n    @model_validator(mode=\"after\")\n    def _validate_url(self) -> FileUrl:\n        \"\"\"Validate URL format.\"\"\"\n        if not self.url.startswith((\"http://\", \"https://\")):\n            raise ValueError(f\"Invalid URL scheme: {self.url}\")\n        return self\n\n    @property\n    def content_type(self) -> str:\n        \"\"\"Get the content type, guessing from URL extension if not set.\"\"\"\n        if self._content_type is None:\n            self._content_type = self._guess_content_type()\n        return self._content_type\n\n    def _guess_content_type(self) -> str:\n        \"\"\"Guess content type from URL extension.\"\"\"\n        from urllib.parse import urlparse\n\n        parsed = urlparse(self.url)\n        path = parsed.path\n        guessed, _ = mimetypes.guess_type(path)\n        return guessed or \"application/octet-stream\"\n","sourceCodeStart":491,"sourceCodeEnd":527,"githubUrl":"https://github.com/crewAIInc/crewAI/blob/754d7323beb2fd042e33444a115ea2d5a47193f0/lib/crewai-files/src/crewai_files/core/sources.py#L491-L527","documentation":"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).","triggerScenarios":"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.","commonSituations":"Cloud-storage URIs pasted directly; user input missing the protocol; URLs normalized to lowercase-host but uppercase scheme; pretrained-pipeline configs referencing file:// paths.","solutions":["Use an http(s) URL: download a presigned URL for cloud objects (S3/GCS) instead of the native URI.","Prepend 'https://' when the scheme is missing but the host is known.","For local files use FilePath instead of a file:// URL."],"exampleFix":"# before\nsrc = FileUrl(url=\"s3://bucket/report.pdf\")\n\n# after\nsrc = FileUrl(url=\"https://bucket.s3.amazonaws.com/report.pdf?X-Amz-...\")","handlingStrategy":"type-guard","validationCode":"def is_http_url(u: str) -> bool:\n    return u.startswith((\"http://\", \"https://\"))","typeGuard":"def as_url_source(u: str):\n    if u.startswith((\"http://\", \"https://\")):\n        return FileUrl(url=u)\n    if u.startswith((\"s3://\", \"gs://\")):\n        raise TypeError(\"presign cloud URLs to https before use\")\n    return FilePath(path=Path(u))  # local path","tryCatchPattern":"try:\n    FileUrl(url=value)\nexcept ValidationError as e:\n    if \"Invalid URL scheme\" in str(e):\n        FileUrl(url=\"https://\" + value.lstrip(\"/\"))  # only when value is a bare host/path","preventionTips":["Normalize scheme to lowercase http(s) at the input boundary.","Presign s3:// and gs:// URIs into https URLs before handing them to FileUrl."],"tags":["validation","url","file-sources"],"backgroundTag":null,"analyzedSha":"754d7323beb2fd042e33444a115ea2d5a47193f0","analyzedAt":"2026-08-15T04:06:56.746Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}