{"record":{"id":"34e212ae214c13c8","repo":"FlowiseAI/Flowise","slug":"you-do-not-have-permission-to-delete-any-chatflow","errorCode":null,"errorMessage":"You do not have permission to delete any chatflow types","messagePattern":"You do not have permission to delete any chatflow types","errorType":"exception","errorClass":"InternalFlowiseError","httpStatus":403,"severity":"error","filePath":"packages/server/src/controllers/chatflows/index.ts","lineNumber":82,"sourceCode":"            throw new InternalFlowiseError(\n                StatusCodes.NOT_FOUND,\n                `Error: chatflowsController.deleteChatflow - workspace ${workspaceId} not found!`\n            )\n        }\n        const userPermittedTypes: EnumChatflowType[] = []\n        const permissions = req.user!.permissions\n        if (req.user?.isOrganizationAdmin) {\n            userPermittedTypes.push(EnumChatflowType.CHATFLOW)\n            userPermittedTypes.push(EnumChatflowType.AGENTFLOW)\n            userPermittedTypes.push(EnumChatflowType.MULTIAGENT)\n            userPermittedTypes.push(EnumChatflowType.ASSISTANT)\n        } else {\n            if (permissions.includes(`chatflows:delete`)) userPermittedTypes.push(EnumChatflowType.CHATFLOW)\n            if (permissions.includes(`agentflows:delete`)) userPermittedTypes.push(EnumChatflowType.AGENTFLOW)\n            if (permissions.includes(`agentflows:delete`)) userPermittedTypes.push(EnumChatflowType.MULTIAGENT)\n            if (permissions.includes(`assistants:delete`)) userPermittedTypes.push(EnumChatflowType.ASSISTANT)\n            if (userPermittedTypes.length === 0)\n                throw new InternalFlowiseError(StatusCodes.FORBIDDEN, `You do not have permission to delete any chatflow types`)\n        }\n        const apiResponse = await chatflowsService.deleteChatflow(req.params.id, orgId, workspaceId, userPermittedTypes)\n        return res.json(apiResponse)\n    } catch (error) {\n        next(error)\n    }\n}\n\nconst getAllChatflows = async (req: Request, res: Response, next: NextFunction) => {\n    try {\n        const { page, limit } = getPageAndLimitParams(req)\n\n        const apiResponse = await chatflowsService.getAllChatflows(\n            req.query?.type as ChatflowType,\n            req.user?.activeWorkspaceId,\n            page,\n            limit\n        )","sourceCodeStart":64,"sourceCodeEnd":100,"githubUrl":"https://github.com/FlowiseAI/Flowise/blob/abe4a8601a058047b350c260676826e21dd14101/packages/server/src/controllers/chatflows/index.ts#L64-L100","documentation":"Thrown by deleteChatflow when a non-org-admin user lacks every chatflow-delete permission (chatflows:delete, agentflows:delete, assistants:delete). Returns FORBIDDEN (403). This is an intentional RBAC denial, not a validation or auth-context failure — the user is known but is not allowed to delete any chatflow type.","triggerScenarios":"A non-admin user calls DELETE /api/v1/chatflows/:id. The code builds userPermittedTypes from req.user.permissions; if none of the delete scopes are present, the array stays empty and this throws.","commonSituations":"Viewer/read-only role attempting a delete; custom role missing the chatflows:delete permission; org admin flag (isOrganizationAdmin) is false due to a stale token even though the user should be admin; permission string typo in the role definition.","solutions":["Grant the user a role containing chatflows:delete (and/or agentflows:delete, assistants:delete) via the org admin UI.","If the user is supposed to be an org admin, verify isOrganizationAdmin is true in their current token — re-login if the role changed.","Confirm the permission strings in the role definition match exactly (chatflows:delete, etc.).","Have an admin perform the delete, or use a service account with the correct scope."],"exampleFix":"// before: viewer role calls delete -> 403\n// after: admin grants 'chatflows:delete' to the user's role\n// then the same call succeeds\nawait api.delete(`/api/v1/chatflows/${id}`)","handlingStrategy":"try-catch","validationCode":"function canDeleteAnyChatflowType(user): boolean {\n  if (!user) return false\n  if ((user as any).isOrganizationAdmin) return true\n  const perms: string[] = (user as any).permissions ?? []\n  return perms.includes('chatflows:delete')\n    || perms.includes('agentflows:delete')\n    || perms.includes('assistants:delete')\n}\nif (!canDeleteAnyChatflowType(currentUser)) {\n  // surface an 'insufficient permissions' UI instead of calling delete\n}","typeGuard":"function isDeletionAuthorizedUser(u: unknown): boolean {\n  if (typeof u !== 'object' || u === null) return false\n  const user = u as any\n  if (user.isOrganizationAdmin) return true\n  return Array.isArray(user.permissions) && (\n    user.permissions.includes('chatflows:delete') ||\n    user.permissions.includes('agentflows:delete') ||\n    user.permissions.includes('assistants:delete')\n  )\n}","tryCatchPattern":"try {\n  await api.delete(`/api/v1/chatflows/${id}`)\n} catch (err) {\n  if (err?.response?.status === 403) {\n    // show 'insufficient permissions — contact an org admin'\n  } else {\n    throw err\n  }\n}","preventionTips":["Check the user's permissions client-side and hide/disable delete for unauthorized roles.","Map roles to required permission strings in a single source of truth.","Re-login after role/permission changes so the token reflects new scopes.","Keep permission string spelling in sync with the server's expected scopes."],"tags":["flowise","express","rbac","authorization","permission","forbidden","controller"],"backgroundTag":null,"analyzedSha":"abe4a8601a058047b350c260676826e21dd14101","analyzedAt":"2026-08-12T16:04:40.823Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}