{"record":{"id":"6469410624c08656","repo":"invoke-ai/InvokeAI","slug":"invalid-workflow-meta-version-version","errorCode":null,"errorMessage":"Invalid workflow meta version: {version}","messagePattern":"Invalid workflow meta version: (.+?)","errorType":"validation","errorClass":null,"httpStatus":400,"severity":"error","filePath":"invokeai/app/services/workflow_records/workflow_records_common.py","lineNumber":51,"sourceCode":"    IsPublic = \"is_public\"\n\n\nclass WorkflowCategory(str, Enum, metaclass=MetaEnum):\n    User = \"user\"\n    Default = \"default\"\n\n\nclass WorkflowMeta(BaseModel):\n    version: str = Field(description=\"The version of the workflow schema.\")\n    category: WorkflowCategory = Field(description=\"The category of the workflow (user or default).\")\n\n    @field_validator(\"version\")\n    def validate_version(cls, version: str):\n        try:\n            semver.Version.parse(version)\n            return version\n        except Exception:\n            raise ValueError(f\"Invalid workflow meta version: {version}\")\n\n    def to_semver(self) -> semver.Version:\n        return semver.Version.parse(self.version)\n\n\nclass WorkflowWithoutID(BaseModel):\n    name: str = Field(description=\"The name of the workflow.\")\n    author: str = Field(description=\"The author of the workflow.\")\n    description: str = Field(description=\"The description of the workflow.\")\n    version: str = Field(description=\"The version of the workflow.\")\n    contact: str = Field(description=\"The contact of the workflow.\")\n    tags: str = Field(description=\"The tags of the workflow.\")\n    notes: str = Field(description=\"The notes of the workflow.\")\n    exposedFields: list[ExposedField] = Field(description=\"The exposed fields of the workflow.\")\n    meta: WorkflowMeta = Field(description=\"The meta of the workflow.\")\n    # TODO(psyche): nodes, edges and form are very loosely typed - they are strictly modeled and checked on the frontend.\n    nodes: list[dict[str, JsonValue]] = Field(description=\"The nodes of the workflow.\")\n    edges: list[dict[str, JsonValue]] = Field(description=\"The edges of the workflow.\")","sourceCodeStart":33,"sourceCodeEnd":69,"githubUrl":"https://github.com/invoke-ai/InvokeAI/blob/0b6a024f2ff6a86bfb953dcdb9cc504ef7397a06/invokeai/app/services/workflow_records/workflow_records_common.py#L33-L69","documentation":"WorkflowMeta requires a 'version' field that parses as a valid semver string (semver.Version.parse). The pydantic field_validator raises ValueError when the supplied version string is not valid semantic versioning, e.g. '1.0', 'v1.0.0', or 'abc'.","triggerScenarios":"Creating or importing a workflow whose meta.version is missing/None, uses a 'v' prefix, has fewer than 3 components, or contains non-numeric prerelease parts.","commonSituations":"Hand-authored workflow JSON files, exports from other tools or older InvokeAI versions with non-semver version fields, templates copied with placeholder versions.","solutions":["Change meta.version to a valid semver string like '1.0.0'","Use to_semver-compatible formatting: MAJOR.MINOR.PATCH with optional -prerelease","If importing many workflows, run a bulk fixer that rewrites invalid versions to '1.0.0'"],"exampleFix":"// before\n{\"meta\": {\"version\": \"1.0\"}}\n// after\n{\"meta\": {\"version\": \"1.0.0\"}}","handlingStrategy":"validation","validationCode":"import semver\ndef valid_workflow_version(v: str) -> bool:\n    try:\n        semver.Version.parse(v)\n        return True\n    except Exception:\n        return False","typeGuard":"def is_semver_string(v: object) -> bool:\n    return isinstance(v, str) and valid_workflow_version(v)","tryCatchPattern":"try:\n    wf = WorkflowWithoutID.model_validate(data)\nexcept ValueError as e:\n    if str(e).startswith(\"Invalid workflow meta version\"):\n        data[\"meta\"][\"version\"] = \"1.0.0\"\n        wf = WorkflowWithoutID.model_validate(data)\n    else:\n        raise","preventionTips":["Always write versions as MAJOR.MINOR.PATCH (no 'v' prefix)","Validate workflow JSON exports with the pydantic model before archiving","Pin a project convention like bumping PATCH per workflow edit"],"tags":["pydantic","validation","semver"],"backgroundTag":"schema-validation-failed","analyzedSha":"0b6a024f2ff6a86bfb953dcdb9cc504ef7397a06","analyzedAt":"2026-08-29T04:46:49.967Z","schemaVersion":2},"datasetVersion":"2026-08-29T07:17:48.351Z"}