mastra-ai/mastra · error · MastraError
DURABLE_AGENT_RECOVER_LEASE_ACQUIRE_FAILED
DURABLE_AGENT_RECOVER_LEASE_ACQUIRE_FAILED
Error message
DurableAgent "${this.name}" recover(${runId}): failed to acquire the recovery lease. What it means
#acquireRecoveryLease asks the configured LeaseProvider to acquire a distributed lease for the recovery key. If provider.acquireLease() itself throws (backend unreachable, auth failure, misconfigured provider), the error is wrapped as this SYSTEM-category MastraError. This differs from 1056: here the lease backend errored, rather than reporting the lease as held by someone else.
Source
Thrown at packages/core/src/agent/durable/durable-agent.ts:589
const localOwner = localRecoveryClaims.get(key);
if (localOwner) {
throw new MastraError({
id: 'DURABLE_AGENT_RECOVER_ALREADY_IN_PROGRESS',
domain: ErrorDomain.AGENT,
category: ErrorCategory.USER,
text: `DurableAgent "${this.name}" recover(${runId}): another process is already recovering this run.`,
details: { agentName: this.name, runId },
});
}
localRecoveryClaims.set(key, owner);
const leaseAcquireStartedAt = Date.now();
let acquired: Awaited<ReturnType<LeaseProvider['acquireLease']>>;
try {
acquired = await provider.acquireLease(key, owner, RECOVERY_LEASE_TTL_MS);
} catch (cause) {
if (localRecoveryClaims.get(key) === owner) localRecoveryClaims.delete(key);
throw new MastraError(
{
id: 'DURABLE_AGENT_RECOVER_LEASE_ACQUIRE_FAILED',
domain: ErrorDomain.AGENT,
category: ErrorCategory.SYSTEM,
text: `DurableAgent "${this.name}" recover(${runId}): failed to acquire the recovery lease.`,
details: { agentName: this.name, runId },
},
cause,
);
}
if (!acquired.acquired) {
if (localRecoveryClaims.get(key) === owner) localRecoveryClaims.delete(key);
throw new MastraError({
id: 'DURABLE_AGENT_RECOVER_ALREADY_IN_PROGRESS',
domain: ErrorDomain.AGENT,
category: ErrorCategory.USER,
text: `DurableAgent "${this.name}" recover(${runId}): another process is already recovering this run.`,View on GitHub (pinned to 75dd419e61)
Solutions
- Inspect the `cause` on the thrown error to find the underlying lease-provider failure (connection, auth, timeout).
- Verify the LeaseProvider configuration and connectivity (connection string, credentials, network access) and re-run recover().
- Retry with backoff if the backend failure was transient.
- If no external lease store is intended, check why a real provider was configured instead of NoopLeaseProvider.
Example fix
// before
await agent.recover(runId); // fails when Redis is down
// after
try {
await agent.recover(runId);
} catch (e) {
if (e?.id === 'DURABLE_AGENT_RECOVER_LEASE_ACQUIRE_FAILED') {
await checkLeaseStoreHealth(); // verify/restore Redis, then retry
await agent.recover(runId);
} else throw e;
} Defensive patterns
Strategy: retry
Validate before calling
await leaseProviderHealthy(); // ping/health-check Redis/DB before starting recovery batches
Try / catch
try {
await agent.recover(runId);
} catch (e) {
if (String(e?.id) === 'DURABLE_AGENT_RECOVER_LEASE_ACQUIRE_FAILED') {
await backoffRetry(() => agent.recover(runId), { attempts: 3 }); // transient backend failure
} else throw e;
} Prevention
- Health-check the lease store (Redis/Postgres) as part of startup and before recovery batches.
- Validate lease-provider connection config (URLs, credentials, network) per environment.
- Alert on lease-store outages; add exponential backoff for lease operations.
When it happens
Trigger: Calling agent.recover(runId) when the configured LeaseProvider's backend is unavailable or misconfigured — e.g. Redis/DB connection failure, invalid credentials, network partition — so acquireLease() throws instead of returning { acquired: false }.
Common situations: Lease provider (Redis/Postgres) down or unreachable from the deployment; wrong connection string/env vars in the new environment; firewall blocking the lease store; transient network blip during a recovery burst.
Related errors
- DURABLE_AGENT_RECOVER_ALREADY_IN_PROGRESS
- DURABLE_AGENT_RECOVER_SNAPSHOT_NOT_FOUND
- DURABLE_AGENT_RECOVER_INVALID_SNAPSHOT
- DURABLE_AGENT_RECOVER_AGENT_MISMATCH
- Token exchange failed: ${error}
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/24ebaaa69dc4faf2.
Report an issue: GitHub.