medusajs/medusa · error · MedusaError
You must provide an api key id field when revoking a key.
Error message
You must provide an api key id field when revoking a key.
What it means
Thrown by validateRevokeApiKeys_ when revoking API keys: every entry in the revoke payload must include an id (and subsequently revoked_by). It guards the batch revoke input shape before touching the database.
Source
Thrown at packages/modules/api-key/src/services/api-key-module-service.ts:539
id: apiKey.id,
...data,
} as T)
)
}
return normalizedInput
}
protected async validateRevokeApiKeys_(
data: RevokeApiKeyInput[],
sharedContext: Context = {}
): Promise<void> {
if (!data.length) {
return
}
if (data.some((k) => !k.id)) {
throw new MedusaError(
MedusaError.Types.INVALID_DATA,
`You must provide an api key id field when revoking a key.`
)
}
if (data.some((k) => !k.revoked_by)) {
throw new MedusaError(
MedusaError.Types.INVALID_DATA,
`You must provide a revoked_by field when revoking a key.`
)
}
const revokedApiKeys = await this.apiKeyService_.list(
{
id: data.map((k) => k.id),
type: ApiKeyType.SECRET,
revoked_at: { $lt: new Date() },
},View on GitHub (pinned to 5e06e544a2)
Solutions
- Ensure every element of the revoke data array has a non-empty id string
- When revoking from admin routes, pass the :id route param into the payload explicitly
- Add payload validation before calling the service to fail early with clearer errors
Example fix
// before
await service.revokeApiKeys({
data: [{ revoked_by: "user_1" }],
})
// after
await service.revokeApiKeys({
data: [{ id: "apk_123", revoked_by: "user_1" }],
}) Defensive patterns
Strategy: validation
Validate before calling
const payload = data.filter(d => typeof d.id === 'string' && d.id.length > 0)
if (payload.length !== data.length) {
throw new Error('every revoke entry requires an id')
}
await service.revokeApiKeys({ data: payload }) Type guard
const isRevokeInput = (
d: unknown
): d is { id: string; revoked_by: string } =>
typeof d === 'object' && d !== null &&
typeof (d as any).id === 'string' && (d as any).id.length > 0 &&
typeof (d as any).revoked_by === 'string' Try / catch
try {
await service.revokeApiKeys({ data })
} catch (e) {
if (e.type === 'invalid_data' && /api key id field/.test(e.message)) {
// filter/rebuild payload entries missing id and retry
}
throw e
} Prevention
- Type the revoke payload explicitly and validate ids before calling the service
- When building revoke data from route params, assert the param is non-empty
When it happens
Trigger: Calling apiKeyModuleService.revokeApiKeys with a payload entry missing id — e.g. {data: [{revoked_by: 'x'}]} — or via POST /admin/api-keys/:id/revoke flows where the id isn't propagated into the payload.
Common situations: Custom scripts building revoke payloads dynamically where id can be undefined (bad variable name, optional chaining result); frontend sending an empty id field.
Understand the failure class
Background: "Missing required field" and "field is required" errors: why libraries reject payloads that omit mandatory fields — this error's family across 20 libraries.
Related errors
- You must provide a revoked_by field when revoking a key.
- --paths must be a directory - ${additionalPath}
- --base must be a file - ${baseFile}
- insufficient_inventory
- not_found
AI-assisted analysis of medusajs/medusa@5e06e544a2 (2026-08-27).
Data as JSON: /api/errors/c257d574819b7517.
Report an issue: GitHub.