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

  1. Send permissions as a non-empty array of strings in the update body.
  2. Coerce selected permission values to strings and require at least one on the client.
  3. If the update is meant to be partial, refactor to accept optional permissions and only validate when present.
  4. 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

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


AI-assisted analysis of FlowiseAI/Flowise@abe4a8601a (2026-08-12). Data as JSON: /api/errors/3234c00bc76b34da. Report an issue: GitHub.