{"record":{"id":"c725d3286453428c","repo":"FlowiseAI/Flowise","slug":"error-apikeycontroller-deleteapikey-id-not-prov","errorCode":null,"errorMessage":"Error: apikeyController.deleteApiKey - id not provided!","messagePattern":"Error: apikeyController\\.deleteApiKey - id not provided!","errorType":"validation","errorClass":"InternalFlowiseError","httpStatus":412,"severity":"warning","filePath":"packages/server/src/controllers/apikey/index.ts","lineNumber":80,"sourceCode":"        ) {\n            throw new InternalFlowiseError(\n                StatusCodes.PRECONDITION_FAILED,\n                `Error: apikeyController.updateApiKey - permissions must be an array of strings!`\n            )\n        }\n        const user = req.user as LoggedInUser\n        const apiResponse = await apikeyService.updateApiKey(user, req.params.id, req.body.keyName, req.body.permissions)\n        return res.json(apiResponse)\n    } catch (error) {\n        next(error)\n    }\n}\n\n// Delete api key\nconst deleteApiKey = async (req: Request, res: Response, next: NextFunction) => {\n    try {\n        if (typeof req.params === 'undefined' || !req.params.id) {\n            throw new InternalFlowiseError(StatusCodes.PRECONDITION_FAILED, `Error: apikeyController.deleteApiKey - id not provided!`)\n        }\n        if (!req.user?.activeWorkspaceId) {\n            throw new InternalFlowiseError(StatusCodes.PRECONDITION_FAILED, `Workspace ID is required`)\n        }\n        const apiResponse = await apikeyService.deleteApiKey(req.params.id, req.user?.activeWorkspaceId)\n        return res.json(apiResponse)\n    } catch (error) {\n        next(error)\n    }\n}\n\n// Verify api key\nconst verifyApiKey = async (req: Request, res: Response, next: NextFunction) => {\n    try {\n        if (typeof req.params === 'undefined' || !req.params.apikey) {\n            throw new InternalFlowiseError(StatusCodes.PRECONDITION_FAILED, `Error: apikeyController.verifyApiKey - apikey not provided!`)\n        }\n        const apiResponse = await apikeyService.verifyApiKey(req.params.apikey)","sourceCodeStart":62,"sourceCodeEnd":98,"githubUrl":"https://github.com/FlowiseAI/Flowise/blob/abe4a8601a058047b350c260676826e21dd14101/packages/server/src/controllers/apikey/index.ts#L62-L98","documentation":"Thrown by the Flowise apikey controller's deleteApiKey handler as an InternalFlowiseError with HTTP 412 (PRECONDITION_FAILED). It fires when the request reaches the handler with no id path parameter, i.e. req.params is undefined or req.params.id is falsy. The DELETE route is registered for both '/' and '/:id' (routes/apikey/index.ts:16), so hitting the root path without an id segment lands here. The error is forwarded via next(error) to Express's error middleware, which serializes it as the HTTP response.","triggerScenarios":"Calling DELETE /api/v1/apikey/ (root form, no id segment) rather than DELETE /api/v1/apikey/<id>. A client building the URL from an empty/blank variable such that the final segment is omitted, or an ingress/proxy that strips the trailing path segment. Note: sending the literal string 'undefined' (DELETE /api/v1/apikey/undefined) does NOT trigger this because req.params.id would be the truthy string 'undefined'.","commonSituations":"A frontend 'Delete API key' action fired before a row is selected, so the id variable is empty and the URL collapses to the root. Misconfigured reverse proxy or base-URL normalization that drops the trailing segment. Automated test/cleanup scripts that iterate an empty id list and DELETE the collection root.","solutions":["Call DELETE with a concrete id: DELETE /api/v1/apikey/<id> (never the bare root) — the '/:id' route variant is the one that actually deletes.","Guard the id client-side before building the URL: if id is not a non-empty string, abort the request.","If you operate a proxy/gateway in front of Flowise, confirm it preserves the full path including the final id segment."],"exampleFix":"// before\nawait fetch(`${BASE}/api/v1/apikey/`, { method: 'DELETE', headers })\n\n// after\nif (typeof id !== 'string' || id.trim() === '') throw new Error('id required')\nawait fetch(`${BASE}/api/v1/apikey/${encodeURIComponent(id)}`, { method: 'DELETE', headers })","handlingStrategy":"validation","validationCode":"function assertId(id: unknown): string {\n  if (typeof id !== 'string' || id.trim() === '') {\n    throw new Error('apikey id is required')\n  }\n  return id\n}\nconst id = assertId(selectedId)\nawait fetch(`${BASE}/api/v1/apikey/${encodeURIComponent(id)}`, { method: 'DELETE', headers })","typeGuard":"const isNonEmptyString = (v: unknown): v is string =>\n  typeof v === 'string' && v.trim().length > 0","tryCatchPattern":null,"preventionTips":["Never DELETE the collection root (/api/v1/apikey/); always append a concrete id.","Centralize URL building for delete calls behind a helper that rejects empty ids.","Remember the literal string 'undefined' is truthy — it bypasses this guard, so also guard against stale undefined values leaking into URLs."],"tags":["validation","express","path-param","precondition-failed","flowise","apikey"],"backgroundTag":null,"analyzedSha":"abe4a8601a058047b350c260676826e21dd14101","analyzedAt":"2026-08-12T16:04:40.823Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}