langflow-ai/langflow · warning · HTTPException
Assignment not found
Error message
Assignment not found
What it means
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.
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
Example fix
// before
await api.delete(`/authz/role-assignments/${id}`);
// after
try {
await api.delete(`/authz/role-assignments/${id}`);
} catch (e) {
if (e.status !== 404) throw e; // already revoked
} Defensive patterns
Strategy: try-catch
Validate before calling
const list = await api.get('/authz/role-assignments');
if (!list.some(a => a.id === id)) return; // nothing to revoke Try / catch
try { await revokeAssignment(id); }
catch (e) { if (e.status !== 404) throw e; /* already revoked */ } Prevention
- Treat delete as idempotent in cleanup scripts
- Remove rows optimistically in the UI and reconcile on 404
- Refresh the assignment table after any revoke
When it happens
Trigger: DELETE with an assignment id that was already revoked, an id from a stale admin UI table, or a malformed/random UUID.
Common situations: Two admins revoking the same assignment, refresh lag in the assignments list after a delete, or repeated runs of a cleanup script.
Related errors
- role_id not found
- user_id not found
- Role not found
- A role cannot be its own parent
- Assignment already exists for this user/role/domain
AI-assisted analysis of langflow-ai/langflow@976ec789d2 (2026-08-14).
Data as JSON: /api/errors/909912a615816121.
Report an issue: GitHub.
Appendix: source
Thrown at src/backend/base/langflow/api/v1/authz_role_assignments.py:157
role.name,
payload.user_id,
payload.domain_type,
payload.domain_id,
)
return RoleAssignmentRead.model_validate(assignment)
@router.delete("/{assignment_id}", status_code=status.HTTP_204_NO_CONTENT)
async def delete_assignment(
assignment_id: UUID,
current_user: CurrentActiveUser,
session: DbSession,
) -> None:
"""Revoke a role assignment. Superuser-only."""
_require_superuser(current_user)
assignment = await session.get(AuthzRoleAssignment, assignment_id)
if assignment is None:
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Assignment not found")
user_id = assignment.user_id
role_id = assignment.role_id
domain_type = assignment.domain_type
domain_id = assignment.domain_id
await session.delete(assignment)
await session.commit()
await safe_invalidate_user(
get_authorization_service(),
user_id,
op="role_assignment:delete",
)
await audit_decision(
user_id=current_user.id,
action="role_assignment:delete",
obj=f"user:{user_id}",
result="allow",
details={
"assignment_id": str(assignment_id),View on GitHub (pinned to 976ec789d2)