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

  1. Inspect the `cause` on the thrown error to find the underlying lease-provider failure (connection, auth, timeout).
  2. Verify the LeaseProvider configuration and connectivity (connection string, credentials, network access) and re-run recover().
  3. Retry with backoff if the backend failure was transient.
  4. 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

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


AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30). Data as JSON: /api/errors/24ebaaa69dc4faf2. Report an issue: GitHub.