FlowiseAI/Flowise · warning · InternalFlowiseError
Error: apikeyController.updateApiKey - permissions must be a
Error message
Error: apikeyController.updateApiKey - permissions must be an array of strings!
What it means
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.
Source
Thrown at packages/server/src/controllers/apikey/index.ts:63
}
}
// Update api key
const updateApiKey = async (req: Request, res: Response, next: NextFunction) => {
try {
if (typeof req.params === 'undefined' || !req.params.id) {
throw new InternalFlowiseError(StatusCodes.PRECONDITION_FAILED, `Error: apikeyController.updateApiKey - id not provided!`)
}
if (typeof req.body === 'undefined' || !req.body.keyName) {
throw new InternalFlowiseError(StatusCodes.PRECONDITION_FAILED, `Error: apikeyController.updateApiKey - keyName not provided!`)
}
if (
!req.body.permissions ||
!Array.isArray(req.body.permissions) ||
req.body.permissions.length === 0 ||
!req.body.permissions.every((p: any) => typeof p === 'string')
) {
throw new InternalFlowiseError(
StatusCodes.PRECONDITION_FAILED,
`Error: apikeyController.updateApiKey - permissions must be an array of strings!`
)
}
const user = req.user as LoggedInUser
const apiResponse = await apikeyService.updateApiKey(user, req.params.id, req.body.keyName, req.body.permissions)
return res.json(apiResponse)
} catch (error) {
next(error)
}
}
// Delete api key
const deleteApiKey = async (req: Request, res: Response, next: NextFunction) => {
try {
if (typeof req.params === 'undefined' || !req.params.id) {
throw new InternalFlowiseError(StatusCodes.PRECONDITION_FAILED, `Error: apikeyController.deleteApiKey - id not provided!`)
}View on GitHub (pinned to abe4a8601a)
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.
Example fix
// before
if (!req.body.permissions || !Array.isArray(req.body.permissions) || req.body.permissions.length === 0 || !req.body.permissions.every((p: any) => typeof p === 'string')) {
throw new InternalFlowiseError(StatusCodes.PRECONDITION_FAILED, `Error: apikeyController.updateApiKey - permissions must be an array of strings!`)
}
// after
const perms = req.body?.permissions
if (!Array.isArray(perms) || perms.length === 0 || !perms.every((p: unknown): p is string => typeof p === 'string')) {
throw new InternalFlowiseError(StatusCodes.BAD_REQUEST, 'permissions must be a non-empty array of strings')
} Defensive patterns
Strategy: type-guard
Validate before calling
function requirePermissions(body: any): asserts body is { permissions: string[] } {
const p = body?.permissions
if (!Array.isArray(p) || p.length === 0 || !p.every((x) => typeof x === 'string')) {
throw new InternalFlowiseError(StatusCodes.BAD_REQUEST, 'permissions must be a non-empty array of strings')
}
}
requirePermissions(req.body) Type guard
function isStringArray(value: unknown): value is string[] {
return Array.isArray(value) && value.length > 0 && value.every((x) => typeof x === 'string')
} Try / catch
// Relies on the global error handler mapping InternalFlowiseError.statusCode (412) to HTTP. // If partial updates are intended, only run the check when permissions is present in the body.
Prevention
- 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.
When it happens
Trigger: PUT/PATCH to update-api-key with a valid id and keyName but permissions omitted, empty, not an array, or containing non-string elements.
Common situations: 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.
Related errors
- Error: apikeyController.createApiKey - permissions must be a
- Error: apikeyController.createApiKey - keyName not provided!
- Error: apikeyController.updateApiKey - id not provided!
- Error: apikeyController.updateApiKey - keyName not provided!
- Question and selectedChatModel are required
AI-assisted analysis of FlowiseAI/Flowise@abe4a8601a (2026-08-12).
Data as JSON: /api/errors/3234c00bc76b34da.
Report an issue: GitHub.