{"record":{"id":"43714b17381faf43","repo":"invoke-ai/InvokeAI","slug":"not-authorized-to-update-this-workflow","errorCode":null,"errorMessage":"Not authorized to update this workflow","messagePattern":"Not authorized to update this workflow","errorType":"http","errorClass":"HTTPException","httpStatus":403,"severity":"error","filePath":"invokeai/app/api/routers/workflows.py","lineNumber":91,"sourceCode":"    operation_id=\"update_workflow\",\n    responses={\n        200: {\"model\": WorkflowRecordDTO},\n    },\n)\ndef update_workflow(\n    current_user: CurrentUserOrDefault,\n    workflow: Workflow = Body(description=\"The updated workflow\", embed=True),\n) -> WorkflowRecordDTO:\n    \"\"\"Updates a workflow\"\"\"\n    try:\n        existing = ApiDependencies.invoker.services.workflow_records.get(workflow.id)\n    except WorkflowNotFoundError:\n        raise HTTPException(status_code=404, detail=\"Workflow not found\")\n\n    config = ApiDependencies.invoker.services.configuration\n    if config.multiuser:\n        if not current_user.is_admin and existing.user_id != current_user.user_id:\n            raise HTTPException(status_code=403, detail=\"Not authorized to update this workflow\")\n    user_id = None if current_user.is_admin else current_user.user_id\n    updated = ApiDependencies.invoker.services.workflow_records.update(workflow=workflow, user_id=user_id)\n    ApiDependencies.invoker.services.events.emit_workflow_updated(\n        workflow_id=updated.workflow_id,\n        user_id=updated.user_id,\n        old_is_public=existing.is_public,\n        new_is_public=updated.is_public,\n    )\n    return updated\n\n\n@workflows_router.delete(\n    \"/i/{workflow_id}\",\n    operation_id=\"delete_workflow\",\n)\ndef delete_workflow(\n    current_user: CurrentUserOrDefault,\n    workflow_id: str = Path(description=\"The workflow to delete\"),","sourceCodeStart":73,"sourceCodeEnd":109,"githubUrl":"https://github.com/invoke-ai/InvokeAI/blob/0b6a024f2ff6a86bfb953dcdb9cc504ef7397a06/invokeai/app/api/routers/workflows.py#L73-L109","documentation":"HTTP 403 raised by the update_workflow endpoint in InvokeAI's REST API when multiuser mode is enabled and the authenticated user attempts to update a workflow they do not own. Admins bypass the ownership check. The workflow exists (otherwise a 404 would be raised), but the caller lacks permission.","triggerScenarios":"PUT to /workflows/i/{workflow_id} with config.multiuser=true, where workflow.user_id differs from the current_user.user_id and current_user.is_admin is false.","commonSituations":"Multiuser InvokeAI deployments where a user shares or copies another user's workflow ID and tries to save changes; migrating workflows between user accounts; frontend passing a stale workflow whose user_id changed after a DB migration.","solutions":["Log in as an admin user, which bypasses the ownership check","Operate the workflow under the account that owns it (verify existing.user_id matches your user)","Set multiuser=false in invokeai.yaml if single-user operation is intended (e.g. local instance)","Have an admin reassign the workflow's user_id in the database to the requesting user"],"exampleFix":"// before\nawait fetch(`/api/v1/workflows/i/${foreignWorkflowId}`, {method: 'PUT', body: wf}); // 403\n// after\nconst wf = await fetch(`/api/v1/workflows/i/${ownWorkflowId}`).then(r=>r.json());\nawait fetch(`/api/v1/workflows/i/${wf.workflow_id}`, {method: 'PUT', body: JSON.stringify(wf)});","handlingStrategy":"validation","validationCode":"const wf = await fetch(`/api/v1/workflows/i/${id}`).then(r=>r.json());\nif (wf.user_id !== myUserId && !isAdmin) throw new Error('Not authorized to update this workflow');","typeGuard":"function canModify(wf, user) { return user.is_admin || wf.user_id === user.user_id; }","tryCatchPattern":"try { await updateWorkflow(id, wf); } catch (e) { if (e?.status === 403) { notify('You do not own this workflow'); } else { throw e; } }","preventionTips":["Check workflow.user_id against the current user before opening it for editing","Disable save controls in the UI for workflows not owned by the user","Run non-multiuser instances only when appropriate; otherwise provision per-user workflows"],"tags":["http-403","authorization","multiuser","rest-api"],"backgroundTag":"insufficient-permissions","analyzedSha":"0b6a024f2ff6a86bfb953dcdb9cc504ef7397a06","analyzedAt":"2026-08-29T04:46:49.967Z","schemaVersion":2},"datasetVersion":"2026-08-29T07:17:48.351Z"}