{"record":{"id":"0871406af28becc7","repo":"invoke-ai/InvokeAI","slug":"source-url-must-be-a-string-087140","errorCode":null,"errorMessage":"source_url must be a string","messagePattern":"source_url must be a string","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"invokeai/backend/model_manager/configs/base.py","lineNumber":91,"sourceCode":"    source_type: ModelSourceType = Field(\n        description=\"The type of source\",\n    )\n    source_api_response: str | None = Field(\n        default=None,\n        description=\"The original API response from the source, as stringified JSON.\",\n    )\n    source_url: str | None = Field(\n        default=None,\n        description=\"Optional URL for the model (e.g. download page or model page).\",\n    )\n\n    @field_validator(\"source_url\", mode=\"before\")\n    @classmethod\n    def validate_source_url(cls, v: Any) -> str | None:\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    cover_image: str | None = Field(\n        default=None,\n        description=\"Url for image to preview model\",\n    )\n\n    CONFIG_CLASSES: ClassVar[set[Type[\"Config_Base\"]]] = set()\n    \"\"\"Set of all non-abstract subclasses of Config_Base, for use during model probing. In other words, this is the set\n    of all known model config types.\"\"\"\n\n    model_config = ConfigDict(\n        validate_assignment=True,\n        json_schema_serialization_defaults_required=True,\n        json_schema_mode_override=\"serialization\",\n    )","sourceCodeStart":73,"sourceCodeEnd":109,"githubUrl":"https://github.com/invoke-ai/InvokeAI/blob/0b6a024f2ff6a86bfb953dcdb9cc504ef7397a06/invokeai/backend/model_manager/configs/base.py#L73-L109","documentation":"Pydantic field_validator for source_url on model config base raises ValueError when the supplied value is not a string (and not None/''). InvokeAI records where a model was downloaded from, and this guard keeps the field type-safe before schema validation.","triggerScenarios":"Creating/updating a ModelConfig (e.g. via model install APIs or YAML/DB import) with source_url set to a number, bytes, dict, or other non-string non-empty value.","commonSituations":"Programmatic config construction passing an int or object; deserializing records from another tool where source_url was stored as bytes; YAML with an unquoted value that parses as a non-string type.","solutions":["Coerce the value to str before assigning, or set it to None if unknown.","If the value comes from YAML/JSON, quote or cast it (e.g. str(v)) so it parses as a string.","Omit the field entirely if there is no source URL - None and '' are accepted and normalized to None."],"exampleFix":"// before\nconfig = {'source_url': 12345}\n// after\nconfig = {'source_url': 'https://huggingface.co/repo/model' if src else None}","handlingStrategy":"type-guard","validationCode":"def sanitize_source_url(v):\n    return None if v in (None, '') else (v if isinstance(v, str) else str(v))","typeGuard":"def is_str_or_none(v: object) -> TypeGuard[str | None]:\n    return v is None or isinstance(v, str)","tryCatchPattern":"try:\n    config = MainModelConfig(**cfg)\nexcept ValueError as e:\n    if 'source_url must be a string' in str(e):\n        cfg['source_url'] = str(cfg['source_url'])\n        config = MainModelConfig(**cfg)\n    else:\n        raise","preventionTips":["Coerce unknown source metadata to str or None before building the config.","Validate serialized configs (YAML/JSON) with pydantic in CI before shipping migrations.","Quote string-ish values in YAML so parsers don't turn them into non-strings."],"tags":["invokeai","pydantic","validation","type-mismatch"],"backgroundTag":"schema-validation-failed","analyzedSha":"0b6a024f2ff6a86bfb953dcdb9cc504ef7397a06","analyzedAt":"2026-08-29T04:46:49.967Z","schemaVersion":2},"datasetVersion":"2026-08-29T07:17:48.351Z"}