{"record":{"id":"006b152559598ccf","repo":"langflow-ai/langflow","slug":"role-id-not-found","errorCode":null,"errorMessage":"role_id not found","messagePattern":"role_id not found","errorType":"http","errorClass":"HTTPException","httpStatus":404,"severity":"error","filePath":"src/backend/base/langflow/api/v1/authz_role_assignments.py","lineNumber":99,"sourceCode":"    return [RoleAssignmentRead.model_validate(row) for row in rows]\n\n\n@router.post(\"\", response_model=RoleAssignmentRead, status_code=status.HTTP_201_CREATED)\n@router.post(\"/\", response_model=RoleAssignmentRead, status_code=status.HTTP_201_CREATED)\nasync def create_assignment(\n    payload: RoleAssignmentCreate,\n    current_user: CurrentActiveUser,\n    session: DbSession,\n) -> RoleAssignmentRead:\n    \"\"\"Assign a role to a user. Superuser-only.\"\"\"\n    _require_superuser(current_user)\n\n    user = await session.get(User, payload.user_id)\n    if user is None:\n        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=\"user_id not found\")\n    role = await session.get(AuthzRole, payload.role_id)\n    if role is None:\n        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=\"role_id not found\")\n\n    assignment = AuthzRoleAssignment(\n        user_id=payload.user_id,\n        role_id=payload.role_id,\n        domain_type=payload.domain_type,\n        domain_id=payload.domain_id,\n        assigned_at=datetime.now(timezone.utc),\n        assigned_by=current_user.id,\n    )\n    session.add(assignment)\n    try:\n        await session.commit()\n    except IntegrityError as exc:\n        await session.rollback()\n        raise HTTPException(\n            status_code=status.HTTP_409_CONFLICT,\n            detail=\"Assignment already exists for this user/role/domain\",\n        ) from exc","sourceCodeStart":81,"sourceCodeEnd":117,"githubUrl":"https://github.com/langflow-ai/langflow/blob/976ec789d2886a86de109c044d089d68e96c9a35/src/backend/base/langflow/api/v1/authz_role_assignments.py#L81-L117","documentation":"Raised by POST /api/v1/authz/role-assignments when payload.role_id does not reference an existing AuthzRole row. The user lookup succeeded, but session.get(AuthzRole, payload.role_id) returned None, giving HTTP 404 'role_id not found'.","triggerScenarios":"POST an assignment referencing a custom role that was deleted, a system role id from a different Langflow install, or a role UUID that was regenerated when the authz foundations migration re-seeded roles.","commonSituations":"Hard-coded role UUIDs in provisioning scripts that break when roles are recreated, mixing ids between environments, or referencing a role deleted by another admin between the UI load and the submit.","solutions":["List roles via GET /api/v1/authz/roles and select by name instead of a stored UUID","In scripts, resolve role ids dynamically: find role by name, then assign","Treat as non-retryable: fix the payload rather than retrying"],"exampleFix":"// before\nawait api.post('/authz/role-assignments', { user_id, role_id: '68f1...' });\n\n// after\nconst roles = await api.get('/api/v1/authz/roles');\nconst dev = roles.find(r => r.name === 'developer');\nawait api.post('/authz/role-assignments', { user_id, role_id: dev.id });","handlingStrategy":"validation","validationCode":"const roles = await api.get('/api/v1/authz/roles');\nif (!roles.some(r => r.id === payload.role_id)) throw new Error('role does not exist');","typeGuard":null,"tryCatchPattern":"catch (e) { if (e.status === 404) refreshRolesAndRepick(); }","preventionTips":["Look roles up by name at runtime rather than persisting UUIDs","Create roles before referencing them as parents or assignment targets","Refresh role lists in admin pickers on window focus"],"tags":["authz","rbac","http-404","role-assignments"],"backgroundTag":null,"analyzedSha":"976ec789d2886a86de109c044d089d68e96c9a35","analyzedAt":"2026-08-14T18:23:12.227Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}