payloadcms/payload · error · InvalidConfiguration
`jobs.processingLease.safetyBuffer` must be non-negative and
Error message
`jobs.processingLease.safetyBuffer` must be non-negative and less than `jobs.processingLease.duration`.
What it means
Thrown at sanitize time when `jobs.processingLease.safetyBuffer` is negative or not strictly less than `jobs.processingLease.duration`. The lease model lets a worker claim a job for `duration` ms and reserves `safetyBuffer` ms of slack before another worker can reclaim a stalled job; an invalid relationship between the two would cause double-execution or premature requeueing.
Source
Thrown at packages/payload/src/config/sanitize.ts:255
minWidth: 'x-small',
})
dashboard.defaultLayout ??= [
{
widgetSlug: 'collections',
width: 'full',
} satisfies WidgetInstance,
{
widgetSlug: 'activity',
width: 'small',
} satisfies WidgetInstance,
]
}
export const sanitizeConfig = (incomingConfig: Config): SanitizedConfig => {
const configWithDefaults = addDefaultsToConfig(incomingConfig)
const { duration, safetyBuffer } = configWithDefaults.jobs!.processingLease!
if (!(safetyBuffer! >= 0 && safetyBuffer! < duration!)) {
throw new InvalidConfiguration(
'`jobs.processingLease.safetyBuffer` must be non-negative and less than `jobs.processingLease.duration`.',
)
}
const config: Partial<SanitizedConfig> = sanitizeAdminConfig(configWithDefaults)
if (!config.endpoints) {
config.endpoints = []
}
if (configWithDefaults.collections?.some(({ upload }) => upload)) {
config.endpoints.push(uploadInstructionsEndpoint, ...stagedUploadEndpoints)
}
for (const endpoint of authRootEndpoints) {
config.endpoints.push(endpoint)
}
View on GitHub (pinned to 00c58b35c0)
Solutions
- Ensure `0 <= safetyBuffer < duration` (both in milliseconds), e.g. `duration: 90_000, safetyBuffer: 15_000`.
- If unsure, remove both options and let Payload apply its defaults.
- Re-check after any change to job/queue config in plugins.
Example fix
// before
jobs: { processingLease: { duration: 10_000, safetyBuffer: 30_000 } }
// after
jobs: { processingLease: { duration: 90_000, safetyBuffer: 15_000 } } Defensive patterns
Strategy: validation
Validate before calling
const { duration = 90_000, safetyBuffer = 15_000 } = config.jobs?.processingLease ?? {}
if (!(safetyBuffer >= 0 && safetyBuffer < duration)) {
throw new Error('jobs.processingLease.safetyBuffer must be >= 0 and < duration')
} Type guard
function isValidLease(l: { duration?: number; safetyBuffer?: number }): boolean {
const d = l.duration ?? 90_000, s = l.safetyBuffer ?? 15_000
return s >= 0 && s < d
} Prevention
- Prefer Payload defaults unless you have measured job runtime.
- Both values are milliseconds — re-check units after copying.
- When raising `duration`, ensure `safetyBuffer` stays below it.
When it happens
Trigger: Explicitly setting `jobs.processingLease.safetyBuffer` greater than `duration`; setting a negative safetyBuffer; copying values from another config without recalculating.
Common situations: Tuning job queue reliability settings; long-running tasks prompting an increase of `duration` while leaving `safetyBuffer` larger; misreading the units (both are milliseconds).
Related errors
- ${sanitizedConfig.admin!.user} is not a valid admin user col
- Collection slug already in use: "${config.collections![i]!.s
- storage contains an invalid entry: expected an object with a
- RichText field${field.name ? ` "${field.name}"` : ''} is mis
- Collection config not found for: ${importCollection}
AI-assisted analysis of payloadcms/payload@00c58b35c0 (2026-08-12).
Data as JSON: /api/errors/8313fe28dbcc6c16.
Report an issue: GitHub.