{"record":{"id":"8a31cf597458e309","repo":"invoke-ai/InvokeAI","slug":"default-workflows-cannot-be-updated","errorCode":null,"errorMessage":"Default workflows cannot be updated","messagePattern":"Default workflows cannot be updated","errorType":"validation","errorClass":null,"httpStatus":400,"severity":"error","filePath":"invokeai/app/services/workflow_records/workflow_records_sqlite.py","lineNumber":78,"sourceCode":"        with self._db.transaction() as cursor:\n            workflow_with_id = Workflow(**workflow.model_dump(), id=uuid_string())\n            cursor.execute(\n                \"\"\"--sql\n                INSERT OR IGNORE INTO workflow_library (\n                    workflow_id,\n                    workflow,\n                    user_id,\n                    is_public\n                )\n                VALUES (?, ?, ?, ?);\n                \"\"\",\n                (workflow_with_id.id, workflow_with_id.model_dump_json(), user_id, is_public),\n            )\n        return self.get(workflow_with_id.id)\n\n    def update(self, workflow: Workflow, user_id: Optional[str] = None) -> WorkflowRecordDTO:\n        if workflow.meta.category is WorkflowCategory.Default:\n            raise ValueError(\"Default workflows cannot be updated\")\n\n        with self._db.transaction() as cursor:\n            if user_id is not None:\n                cursor.execute(\n                    \"\"\"--sql\n                    UPDATE workflow_library\n                    SET workflow = ?\n                    WHERE workflow_id = ? AND category = 'user' AND user_id = ?;\n                    \"\"\",\n                    (workflow.model_dump_json(), workflow.id, user_id),\n                )\n            else:\n                cursor.execute(\n                    \"\"\"--sql\n                    UPDATE workflow_library\n                    SET workflow = ?\n                    WHERE workflow_id = ? AND category = 'user';\n                    \"\"\",","sourceCodeStart":60,"sourceCodeEnd":96,"githubUrl":"https://github.com/invoke-ai/InvokeAI/blob/0b6a024f2ff6a86bfb953dcdb9cc504ef7397a06/invokeai/app/services/workflow_records/workflow_records_sqlite.py#L60-L96","documentation":"update() refuses to modify workflows whose meta.category is WorkflowCategory.Default. Default workflows shipped with the application are treated as immutable through the public API to keep them in sync with app releases.","triggerScenarios":"Calling update(workflow) where workflow.meta.category is Default; loading a default workflow in the editor and saving it back unchanged in category.","commonSituations":"Bulk edit scripts iterating all workflows without filtering category; user duplicating-but-not-actually-copying a default workflow (same id/category); migrations that touch every row.","solutions":["Duplicate the workflow as a Custom-category copy and update that instead","Skip Default-category workflows in update loops (filter on workflow.meta.category)","If a shipped default truly needs changes, update it via the app's default-workflow sync mechanism, not update()"],"exampleFix":"// before\nfor wf in all_workflows:\n    service.update(wf)\n// after\nfor wf in all_workflows:\n    if wf.meta.category is not WorkflowCategory.Default:\n        service.update(wf)","handlingStrategy":"validation","validationCode":"if workflow.meta.category is WorkflowCategory.Default:\n    raise SkipUpdate(f\"{workflow.id} is a default workflow; duplicate it first\")","typeGuard":"def is_custom(workflow: Workflow) -> bool:\n    return workflow.meta.category is not WorkflowCategory.Default","tryCatchPattern":"try:\n    record = service.update(workflow)\nexcept ValueError as e:\n    if \"Default workflows cannot be updated\" in str(e):\n        record = duplicate_as_custom(service, workflow)  # create Custom copy, edit that\n    else:\n        raise","preventionTips":["Filter Default-category workflows out of bulk update jobs","Present defaults as read-only in UIs and scripts","Use service.create with a Custom category to make editable copies"],"tags":["workflow","validation","business-rule"],"backgroundTag":"forbidden-operation","analyzedSha":"0b6a024f2ff6a86bfb953dcdb9cc504ef7397a06","analyzedAt":"2026-08-29T04:46:49.967Z","schemaVersion":2},"datasetVersion":"2026-08-29T07:17:48.351Z"}