{"record":{"id":"6a46d96b6bd92a56","repo":"invoke-ai/InvokeAI","slug":"default-workflows-cannot-be-deleted","errorCode":null,"errorMessage":"Default workflows cannot be deleted","messagePattern":"Default workflows cannot be deleted","errorType":"validation","errorClass":null,"httpStatus":400,"severity":"error","filePath":"invokeai/app/services/workflow_records/workflow_records_sqlite.py","lineNumber":103,"sourceCode":"                    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                    \"\"\",\n                    (workflow.model_dump_json(), workflow.id),\n                )\n        return self.get(workflow.id)\n\n    def delete(self, workflow_id: str, user_id: Optional[str] = None) -> None:\n        if self.get(workflow_id).workflow.meta.category is WorkflowCategory.Default:\n            raise ValueError(\"Default workflows cannot be deleted\")\n\n        with self._db.transaction() as cursor:\n            if user_id is not None:\n                cursor.execute(\n                    \"\"\"--sql\n                    DELETE from workflow_library\n                    WHERE workflow_id = ? AND category = 'user' AND user_id = ?;\n                    \"\"\",\n                    (workflow_id, user_id),\n                )\n            else:\n                cursor.execute(\n                    \"\"\"--sql\n                    DELETE from workflow_library\n                    WHERE workflow_id = ? AND category = 'user';\n                    \"\"\",\n                    (workflow_id,),\n                )","sourceCodeStart":85,"sourceCodeEnd":121,"githubUrl":"https://github.com/invoke-ai/InvokeAI/blob/0b6a024f2ff6a86bfb953dcdb9cc504ef7397a06/invokeai/app/services/workflow_records/workflow_records_sqlite.py#L85-L121","documentation":"delete() checks the stored workflow's category first (via self.get) and refuses to delete Default-category workflows. This protects built-in workflows shipped with the application from being removed by user actions.","triggerScenarios":"Calling delete(workflow_id) on a workflow whose stored record has meta.category == WorkflowCategory.Default; batch-deletion scripts sweeping all ids.","commonSituations":"'Delete all' UI actions or cleanup scripts; DB cleanup jobs not filtering category; attempts to remove a default workflow that appears duplicated in the library.","solutions":["Only delete Custom-category workflows; filter the id list before calling delete","Catch ValueError per id in batch deletes and log skips for defaults","If the default workflow must go away, it should be removed in the app's default-workflow definitions/sync, not via delete()"],"exampleFix":"# before\nfor wf_id in all_ids:\n    service.delete(wf_id)\n# after\nfor wf_id in all_ids:\n    if service.get(wf_id).workflow.meta.category is not WorkflowCategory.Default:\n        service.delete(wf_id)","handlingStrategy":"validation","validationCode":"record = service.get(workflow_id)\nif record.workflow.meta.category is WorkflowCategory.Default:\n    raise SkipDelete(f\"{workflow_id} is a default workflow\")","typeGuard":"def deletable(record: WorkflowRecordDTO) -> bool:\n    return record.workflow.meta.category is not WorkflowCategory.Default","tryCatchPattern":"try:\n    service.delete(workflow_id)\nexcept ValueError as e:\n    if \"Default workflows cannot be deleted\" in str(e):\n        logger.info(\"skipped default workflow %s\", workflow_id)\n    else:\n        raise","preventionTips":["Check category via get() before batch deletes","Exclude default workflow ids (queryable by category) from cleanup jobs","Never assume every id in the library is user-deletable"],"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"}