{"record":{"id":"8ccdbfa043451f8f","repo":"FlowiseAI/Flowise","slug":"error-apikeycontroller-createapikey-permissions","errorCode":null,"errorMessage":"Error: apikeyController.createApiKey - permissions must be an array of strings!","messagePattern":"Error: apikeyController\\.createApiKey - permissions must be an array of strings!","errorType":"validation","errorClass":"InternalFlowiseError","httpStatus":412,"severity":"warning","filePath":"packages/server/src/controllers/apikey/index.ts","lineNumber":35,"sourceCode":"        const apiResponse = await apikeyService.getAllApiKeys(user, page, limit)\n        return res.status(StatusCodes.OK).json(apiResponse)\n    } catch (error) {\n        next(error)\n    }\n}\n\nconst createApiKey = async (req: Request, res: Response, next: NextFunction) => {\n    try {\n        if (typeof req.body === 'undefined' || !req.body.keyName) {\n            throw new InternalFlowiseError(StatusCodes.PRECONDITION_FAILED, `Error: apikeyController.createApiKey - 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.createApiKey - permissions must be an array of strings!`\n            )\n        }\n        const user = req.user as LoggedInUser\n        const apiResponse = await apikeyService.createApiKey(user, req.body.keyName, req.body.permissions)\n        return res.json(apiResponse)\n    } catch (error) {\n        next(error)\n    }\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        }","sourceCodeStart":17,"sourceCodeEnd":53,"githubUrl":"https://github.com/FlowiseAI/Flowise/blob/abe4a8601a058047b350c260676826e21dd14101/packages/server/src/controllers/apikey/index.ts#L17-L53","documentation":"createApiKey handler validates that req.body.permissions is a non-empty array where every element is a string. Failing any of those checks throws InternalFlowiseError 412. Permissions are stored on the key and used for authorization, so the shape must be correct before the service layer is reached.","triggerScenarios":"POST to create-api-key with permissions omitted, set to a single string instead of an array, an empty array, or an array containing non-string entries (numbers, objects, null).","commonSituations":"Client sends permissions: 'chatflows:read' (string) instead of ['chatflows:read']. Frontend sends [] when nothing selected. Mixed-type array from a loosely typed form. Legacy client using a comma-separated string.","solutions":["Send permissions as a non-empty array of strings, e.g. [\"chatflows:read\", \"chatflows:write\"].","On the client, coerce selected permission values to strings and ensure at least one is chosen.","If accepting a string shorthand, wrap it client-side: [].concat(value).","Add a JSON-schema validator at the route to reject malformed arrays 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.createApiKey - permissions must be an array of strings!`)\n}\n\n// after: clearer status and message\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// To improve, change the thrown status to BAD_REQUEST (400) for clearer client semantics.","preventionTips":["Send permissions as a non-empty array of strings.","Coerce selected permission values to strings and require at least one on the client.","Wrap single-string shorthand into an array before sending.","Add a JSON-schema validator 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"}