{"record":{"id":"93add9baf19e1361","repo":"invoke-ai/InvokeAI","slug":"source-url-must-be-an-http-or-https-url","errorCode":null,"errorMessage":"source_url must be an http or https URL","messagePattern":"source_url must be an http or https URL","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"invokeai/app/services/model_records/model_records_base.py","lineNumber":104,"sourceCode":"\nclass ModelRecordChanges(BaseModelExcludeNull):\n    \"\"\"A set of changes to apply to a model.\"\"\"\n\n    # Changes applicable to all models\n    source: Optional[str] = Field(description=\"original source of the model\", default=None)\n    source_type: Optional[ModelSourceType] = Field(description=\"type of model source\", default=None)\n    source_api_response: Optional[str] = Field(description=\"metadata from remote source\", default=None)\n    source_url: Optional[str] = Field(description=\"Optional URL for the model (e.g. download page)\", default=None)\n\n    @field_validator(\"source_url\", mode=\"before\")\n    @classmethod\n    def validate_source_url(cls, v: Any) -> Optional[str]:\n        if v is None or v == \"\":\n            return None\n        if not isinstance(v, str):\n            raise ValueError(\"source_url must be a string\")\n        if not v.startswith((\"https://\", \"http://\")):\n            raise ValueError(\"source_url must be an http or https URL\")\n        return v\n\n    name: Optional[str] = Field(description=\"Name of the model.\", default=None)\n    path: Optional[str] = Field(description=\"Path to the model.\", default=None)\n    description: Optional[str] = Field(description=\"Model description\", default=None)\n    base: Optional[BaseModelType] = Field(description=\"The base model.\", default=None)\n    type: Optional[ModelType] = Field(description=\"Type of model\", default=None)\n    key: Optional[str] = Field(description=\"Database ID for this model\", default=None)\n    hash: Optional[str] = Field(description=\"hash of model file\", default=None)\n    file_size: Optional[int] = Field(description=\"Size of model file\", default=None)\n    format: Optional[str] = Field(description=\"format of model file\", default=None)\n    trigger_phrases: Optional[set[str]] = Field(description=\"Set of trigger phrases for this model\", default=None)\n    default_settings: Optional[\n        MainModelDefaultSettings\n        | LoraModelDefaultSettings\n        | ControlAdapterDefaultSettings\n        | ExternalApiModelDefaultSettings\n    ] = Field(description=\"Default settings for this model\", default=None)","sourceCodeStart":86,"sourceCodeEnd":122,"githubUrl":"https://github.com/invoke-ai/InvokeAI/blob/0b6a024f2ff6a86bfb953dcdb9cc504ef7397a06/invokeai/app/services/model_records/model_records_base.py#L86-L122","documentation":"The same before-validator also enforces that a non-empty source_url string be an http or https URL. Any string lacking the https:// or http:// prefix raises this ValueError during model record validation.","triggerScenarios":"Submitting source_url values like 'huggingface.co/org/repo' (scheme missing), 'ftp://...', 'file:///models/x', or a bare repo id 'org/repo'.","commonSituations":"Users typing a repo path without the scheme in install forms; config files with shorthand URLs; copying paths from a browser address bar minus the scheme; CLI scripts concatenating host+path manually.","solutions":["Prefix the value with https:// (HuggingFace sources are https).","Use full absolute URLs, not repo ids or file paths — use path/local model fields for files.","Add client-side validation that the string starts with https:// or http:// before submitting."],"exampleFix":"// before\nconst payload = { source_url: 'huggingface.co/stabilityai/sd-turbo' };\n// after\nconst payload = { source_url: 'https://huggingface.co/stabilityai/sd-turbo' };","handlingStrategy":"validation","validationCode":"function isValidSourceUrl(v) {\n  if (v === null || v === '') return true;\n  return typeof v === 'string' && /^https?:\\/\\//.test(v);\n}\nif (!isValidSourceUrl(payload.source_url)) {\n  payload.source_url = 'https://' + String(payload.source_url).replace(/^\\/+/, '');\n}","typeGuard":"function isHttpUrl(v: unknown): v is string {\n  return typeof v === 'string' && v.startsWith('https://') || typeof v === 'string' && v.startsWith('http://');\n}","tryCatchPattern":"try {\n  await api.addModelRecord(payload);\n} catch (e) {\n  if (String(e).includes('http or https URL')) {\n    payload.source_url = 'https://' + payload.source_url;\n    return api.addModelRecord(payload);\n  }\n  throw e;\n}","preventionTips":["Always include the https:// scheme in source URLs","Use full URLs, not bare org/repo identifiers","For local files use the path field, not source_url"],"tags":["pydantic","validation","url-validation","model-records"],"backgroundTag":"schema-validation-failed","analyzedSha":"0b6a024f2ff6a86bfb953dcdb9cc504ef7397a06","analyzedAt":"2026-08-29T04:46:49.967Z","schemaVersion":2},"datasetVersion":"2026-08-29T07:17:48.351Z"}