{"record":{"id":"3234c00bc76b34da","repo":"FlowiseAI/Flowise","slug":"error-apikeycontroller-updateapikey-permissions","errorCode":null,"errorMessage":"Error: apikeyController.updateApiKey - permissions must be an array of strings!","messagePattern":"Error: apikeyController\\.updateApiKey - permissions must be an array of strings!","errorType":"validation","errorClass":"InternalFlowiseError","httpStatus":412,"severity":"warning","filePath":"packages/server/src/controllers/apikey/index.ts","lineNumber":63,"sourceCode":"    }\n}\n\n// Update api key\nconst updateApiKey = 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.updateApiKey - id not provided!`)\n        }\n        if (typeof req.body === 'undefined' || !req.body.keyName) {\n            throw new InternalFlowiseError(StatusCodes.PRECONDITION_FAILED, `Error: apikeyController.updateApiKey - keyName not provided!`)\n        }\n        if (\n            !req.body.permissions ||\n            !Array.isArray(req.body.permissions) ||\n            req.body.permissions.length === 0 ||\n            !req.body.permissions.every((p: any) => typeof p === 'string')\n        ) {\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        }","sourceCodeStart":45,"sourceCodeEnd":81,"githubUrl":"https://github.com/FlowiseAI/Flowise/blob/abe4a8601a058047b350c260676826e21dd14101/packages/server/src/controllers/apikey/index.ts#L45-L81","documentation":"updateApiKey handler validates req.body.permissions as a non-empty array of strings, mirroring createApiKey. Failing the check throws InternalFlowiseError 412. Because the update path overwrites permissions, the new set must be well-formed before the service call.","triggerScenarios":"PUT/PATCH to update-api-key with a valid id and keyName but permissions omitted, empty, not an array, or containing non-string elements.","commonSituations":"Client sends permissions as a single string or comma-separated value. Empty array sent when no permissions selected. Mixed-type array from a loosely typed client. Partial-update client that omits permissions but the handler still requires it.","solutions":["Send permissions as a non-empty array of strings in the update body.","Coerce selected permission values to strings and require at least one on the client.","If the update is meant to be partial, refactor to accept optional permissions and only validate when present.","Add schema validation at the route to reject malformed arrays early with a clearer message."],"exampleFix":"// before\nif (!req.body.permissions || !Array.isArray(req.body.permissions) || req.body.permissions.length === 0 || !req.body.permissions.every((p: any) => typeof p === 'string')) {\n    throw new InternalFlowiseError(StatusCodes.PRECONDITION_FAILED, `Error: apikeyController.updateApiKey - permissions must be an array of strings!`)\n}\n\n// after\nconst perms = req.body?.permissions\nif (!Array.isArray(perms) || perms.length === 0 || !perms.every((p: unknown): p is string => typeof p === 'string')) {\n    throw new InternalFlowiseError(StatusCodes.BAD_REQUEST, 'permissions must be a non-empty array of strings')\n}","handlingStrategy":"type-guard","validationCode":"function requirePermissions(body: any): asserts body is { permissions: string[] } {\n    const p = body?.permissions\n    if (!Array.isArray(p) || p.length === 0 || !p.every((x) => typeof x === 'string')) {\n        throw new InternalFlowiseError(StatusCodes.BAD_REQUEST, 'permissions must be a non-empty array of strings')\n    }\n}\nrequirePermissions(req.body)","typeGuard":"function isStringArray(value: unknown): value is string[] {\n    return Array.isArray(value) && value.length > 0 && value.every((x) => typeof x === 'string')\n}","tryCatchPattern":"// Relies on the global error handler mapping InternalFlowiseError.statusCode (412) to HTTP.\n// If partial updates are intended, only run the check when permissions is present in the body.","preventionTips":["Send permissions as a non-empty array of strings in the update body.","Coerce selected permission values to strings and require at least one.","For partial updates, make permissions optional and validate only when present.","Add schema validation at the route to reject malformed arrays early."],"tags":["validation","controller","apikey","input-validation","permissions","express"],"backgroundTag":null,"analyzedSha":"abe4a8601a058047b350c260676826e21dd14101","analyzedAt":"2026-08-12T16:04:40.823Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}