{"record":{"id":"909912a615816121","repo":"langflow-ai/langflow","slug":"assignment-not-found","errorCode":null,"errorMessage":"Assignment not found","messagePattern":"Assignment not found","errorType":"http","errorClass":"HTTPException","httpStatus":404,"severity":"warning","filePath":"src/backend/base/langflow/api/v1/authz_role_assignments.py","lineNumber":157,"sourceCode":"        role.name,\n        payload.user_id,\n        payload.domain_type,\n        payload.domain_id,\n    )\n    return RoleAssignmentRead.model_validate(assignment)\n\n\n@router.delete(\"/{assignment_id}\", status_code=status.HTTP_204_NO_CONTENT)\nasync def delete_assignment(\n    assignment_id: UUID,\n    current_user: CurrentActiveUser,\n    session: DbSession,\n) -> None:\n    \"\"\"Revoke a role assignment. Superuser-only.\"\"\"\n    _require_superuser(current_user)\n    assignment = await session.get(AuthzRoleAssignment, assignment_id)\n    if assignment is None:\n        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=\"Assignment not found\")\n    user_id = assignment.user_id\n    role_id = assignment.role_id\n    domain_type = assignment.domain_type\n    domain_id = assignment.domain_id\n    await session.delete(assignment)\n    await session.commit()\n    await safe_invalidate_user(\n        get_authorization_service(),\n        user_id,\n        op=\"role_assignment:delete\",\n    )\n    await audit_decision(\n        user_id=current_user.id,\n        action=\"role_assignment:delete\",\n        obj=f\"user:{user_id}\",\n        result=\"allow\",\n        details={\n            \"assignment_id\": str(assignment_id),","sourceCodeStart":139,"sourceCodeEnd":175,"githubUrl":"https://github.com/langflow-ai/langflow/blob/976ec789d2886a86de109c044d089d68e96c9a35/src/backend/base/langflow/api/v1/authz_role_assignments.py#L139-L175","documentation":"Raised by DELETE /api/v1/authz/role-assignments/{assignment_id} when no AuthzRoleAssignment row with that id exists. The route checks session.get first and returns HTTP 404 before attempting the delete, rollback, cache invalidation, or audit write.","triggerScenarios":"DELETE with an assignment id that was already revoked, an id from a stale admin UI table, or a malformed/random UUID.","commonSituations":"Two admins revoking the same assignment, refresh lag in the assignments list after a delete, or repeated runs of a cleanup script.","solutions":["Refresh the assignments list and confirm the id still exists before deleting","Treat 404 as the desired end state for cleanup scripts (role assignment is gone)","Guard double-revokes in the UI by removing the row optimistically"],"exampleFix":"// before\nawait api.delete(`/authz/role-assignments/${id}`);\n\n// after\ntry {\n  await api.delete(`/authz/role-assignments/${id}`);\n} catch (e) {\n  if (e.status !== 404) throw e; // already revoked\n}","handlingStrategy":"try-catch","validationCode":"const list = await api.get('/authz/role-assignments');\nif (!list.some(a => a.id === id)) return; // nothing to revoke","typeGuard":null,"tryCatchPattern":"try { await revokeAssignment(id); }\ncatch (e) { if (e.status !== 404) throw e; /* already revoked */ }","preventionTips":["Treat delete as idempotent in cleanup scripts","Remove rows optimistically in the UI and reconcile on 404","Refresh the assignment table after any revoke"],"tags":["authz","rbac","http-404","role-assignments"],"backgroundTag":null,"analyzedSha":"976ec789d2886a86de109c044d089d68e96c9a35","analyzedAt":"2026-08-14T18:23:12.227Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}