{"record":{"id":"6f9af318b45d08f9","repo":"FlowiseAI/Flowise","slug":"error-chatflowscontroller-checkifchatflowhaschang-6f9af3","errorCode":null,"errorMessage":"Error: chatflowsController.checkIfChatflowHasChanged - active workspace ID not found!","messagePattern":"Error: chatflowsController\\.checkIfChatflowHasChanged - active workspace ID not found!","errorType":"exception","errorClass":"InternalFlowiseError","httpStatus":404,"severity":"error","filePath":"packages/server/src/controllers/chatflows/index.ts","lineNumber":290,"sourceCode":"}\n\nconst checkIfChatflowHasChanged = async (req: Request, res: Response, next: NextFunction) => {\n    try {\n        if (typeof req.params === 'undefined' || !req.params.id) {\n            throw new InternalFlowiseError(\n                StatusCodes.PRECONDITION_FAILED,\n                `Error: chatflowsController.checkIfChatflowHasChanged - id not provided!`\n            )\n        }\n        if (!req.params.lastUpdatedDateTime) {\n            throw new InternalFlowiseError(\n                StatusCodes.PRECONDITION_FAILED,\n                `Error: chatflowsController.checkIfChatflowHasChanged - lastUpdatedDateTime not provided!`\n            )\n        }\n        const workspaceId = req.user?.activeWorkspaceId\n        if (!workspaceId) {\n            throw new InternalFlowiseError(\n                StatusCodes.NOT_FOUND,\n                'Error: chatflowsController.checkIfChatflowHasChanged - active workspace ID not found!'\n            )\n        }\n        const apiResponse = await chatflowsService.checkIfChatflowHasChanged(req.params.id, req.params.lastUpdatedDateTime, workspaceId)\n        return res.json(apiResponse)\n    } catch (error) {\n        next(error)\n    }\n}\n\nconst setWebhookSecret = async (req: Request, res: Response, next: NextFunction) => {\n    try {\n        if (!req.params.id) {\n            throw new InternalFlowiseError(\n                StatusCodes.PRECONDITION_FAILED,\n                `Error: chatflowsController.setWebhookSecret - id not provided!`\n            )","sourceCodeStart":272,"sourceCodeEnd":308,"githubUrl":"https://github.com/FlowiseAI/Flowise/blob/abe4a8601a058047b350c260676826e21dd14101/packages/server/src/controllers/chatflows/index.ts#L272-L308","documentation":"Thrown by checkIfChatflowHasChanged when req.user?.activeWorkspaceId is falsy. Flowise is multi-tenant by workspace; every chatflow operation must be scoped to the caller's active workspace. The guard returns NOT_FOUND (404). The optional chaining means it fires both when the auth middleware never attached req.user and when the user genuinely has no active workspace set.","triggerScenarios":"The request reaches the controller without authentication middleware populating req.user.activeWorkspaceId, or the authenticated user has no activeWorkspaceId in their session/JWT, or the workspace was deleted while the session stayed valid.","commonSituations":"Auth middleware misordering (the route is public or the guard runs before auth), an expired/partial JWT missing the activeWorkspaceId claim, a freshly created user who has not been assigned an active workspace, or a test harness that calls the controller with a stubbed req that omits req.user.","solutions":["Confirm the route is behind the auth middleware that sets req.user.activeWorkspaceId (e.g. the Flowise workspace auth guard) and that the client sends a valid session cookie / API key.","If the user legitimately lacks a workspace, set/switch their active workspace before retrying (Flowise workspace selection flow).","For automated tests, inject req.user = { activeWorkspaceId: '<wsid>' } on the supertest request."],"exampleFix":"// before - calling the endpoint with no auth context\nawait request(app).get(`/api/v1/chatflows/${id}/chatflow-changed/${ts}`)\n// after - authenticate so req.user.activeWorkspaceId is set\nawait request(app)\n  .get(`/api/v1/chatflows/${id}/chatflow-changed/${ts}`)\n  .set('Cookie', sessionCookie)","handlingStrategy":"validation","validationCode":"function assertWorkspace(req: { user?: { activeWorkspaceId?: string } }): string {\n  const ws = req.user?.activeWorkspaceId\n  if (!ws) throw new Error('no active workspace - authenticate or select a workspace')\n  return ws\n}","typeGuard":"const hasActiveWorkspace = (u: unknown): u is { activeWorkspaceId: string } =>\n  typeof u === 'object' && u !== null && typeof (u as any).activeWorkspaceId === 'string' && !!(u as any).activeWorkspaceId","tryCatchPattern":"try { await api.checkIfChanged(id, ts) }\ncatch (e) {\n  if (e.statusCode === 404 && /workspace/i.test(e.message)) { await reAuth(); await api.checkIfChanged(id, ts) }\n}","preventionTips":["Always send a valid session/API key so req.user is populated.","Ensure users are assigned an active workspace at provisioning time.","Order auth/workspace middleware before feature handlers."],"tags":["flowise","controller","validation","workspace","auth","not-found","typescript"],"backgroundTag":null,"analyzedSha":"abe4a8601a058047b350c260676826e21dd14101","analyzedAt":"2026-08-12T16:04:40.823Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}