{"record":{"id":"03c15a46d0cb01f0","repo":"FlowiseAI/Flowise","slug":"error-chatflowscontroller-checkifchatflowhaschang-03c15a","errorCode":null,"errorMessage":"Error: chatflowsController.checkIfChatflowHasChanged - lastUpdatedDateTime not provided!","messagePattern":"Error: chatflowsController\\.checkIfChatflowHasChanged - lastUpdatedDateTime not provided!","errorType":"exception","errorClass":"InternalFlowiseError","httpStatus":412,"severity":"error","filePath":"packages/server/src/controllers/chatflows/index.ts","lineNumber":283,"sourceCode":"            )\n        }\n        const apiResponse = await chatflowsService.getSinglePublicChatbotConfig(req.params.id)\n        return res.json(apiResponse)\n    } catch (error) {\n        next(error)\n    }\n}\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","sourceCodeStart":265,"sourceCodeEnd":301,"githubUrl":"https://github.com/FlowiseAI/Flowise/blob/abe4a8601a058047b350c260676826e21dd14101/packages/server/src/controllers/chatflows/index.ts#L265-L301","documentation":"Thrown by checkIfChatflowHasChanged when the request path is missing the lastUpdatedDateTime segment. Flowise uses this endpoint so clients can poll whether a chatflow changed since a known timestamp; without the timestamp the comparison is meaningless. It is a guard inside the controller (PRECONDITION_FAILED / 412) thrown as an InternalFlowiseError and forwarded to Express error middleware via next(error).","triggerScenarios":"A GET request to the chatflow-change-check route whose path does not include the :lastUpdatedDateTime param, e.g. calling /api/v1/chatflows/:id/... without the timestamp segment, or hitting a route definition that omits the param so req.params.lastUpdatedDateTime resolves to undefined.","commonSituations":"Frontend was upgraded to a newer API contract that renamed/removed the segment; a custom integration or curl call that omitted the timestamp; a route misconfiguration where the Express router forgot to declare :lastUpdatedDateTime so the value is always undefined even when the client sent it in the body.","solutions":["Include lastUpdatedDateTime as a path segment matching the route definition (e.g. GET /api/v1/chatflows/<id>/chatflow-changed/<lastUpdatedDateTime>).","If you control the route, verify the Express router declares :lastUpdatedDateTime in the path string; otherwise the param is always undefined regardless of client input.","If the value belongs in the query string or body, change the controller to read req.query.lastUpdatedDateTime / req.body.lastUpdatedDateTime instead of req.params."],"exampleFix":"// before - client omits the timestamp\nconst r = await fetch(`/api/v1/chatflows/${id}/chatflow-changed`)\n// after - include the last-known timestamp as a path param\nconst r = await fetch(`/api/v1/chatflows/${id}/chatflow-changed/${encodeURIComponent(lastUpdatedDateTime)}`)","handlingStrategy":"validation","validationCode":"function buildChangeCheckUrl(id: string, lastUpdatedDateTime: string): string {\n  if (!id) throw new Error('chatflow id required')\n  if (!lastUpdatedDateTime) throw new Error('lastUpdatedDateTime required')\n  return `/api/v1/chatflows/${encodeURIComponent(id)}/chatflow-changed/${encodeURIComponent(lastUpdatedDateTime)}`\n}","typeGuard":"const isNonEmptyString = (v: unknown): v is string => typeof v === 'string' && v.trim().length > 0","tryCatchPattern":"try {\n  const r = await fetch(buildChangeCheckUrl(id, ts))\n  if (!r.ok) throw await r.json()\n} catch (e) {\n  // 412 here means a path param is missing - re-derive id/ts and retry once\n  if (e.statusCode === 412) console.error('missing path param', e.message)\n}","preventionTips":["Derive request URLs from validated non-empty id/timestamp values only.","Confirm the Express route declares every param the controller reads.","Unit-test the controller with supertest passing all required params."],"tags":["flowise","controller","validation","precondition-failed","path-param","typescript"],"backgroundTag":null,"analyzedSha":"abe4a8601a058047b350c260676826e21dd14101","analyzedAt":"2026-08-12T16:04:40.823Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}