openclaw/openclaw · error · Error

Crabbox operation lease is not ready

Error message

Crabbox operation lease is not ready

What it means

Thrown by leaseFromInspect() when inspect.ready !== true. Even if the lease state is non-terminal, a lease that is not ready cannot guarantee SSH connectivity, so the provider refuses to return it to core bootstrap. This is a plain Error (not WorkerProviderError) because it represents a transient/pending condition rather than a permanent policy violation — and unlike WorkerProviderError it does not trigger lease cleanup at the provision call site.

Source

Thrown at extensions/crabbox/src/crabbox-worker-provider.ts:327

    result.termination === "exit" &&
    (authoritativeLeaseAbsence(result, params.context.id) ||
      alreadyStopped(result, params.context.id))
  ) {
    return;
  }
  throw crabboxCommandError("stop", result);
}

const isTerminalState = (state: string) => DESTROYED_STATES.has(state.toLowerCase());
const isUnusableProvisionState = (state: string) =>
  UNUSABLE_PROVISION_STATES.has(state.toLowerCase());

function leaseFromInspect(inspect: ParsedInspect, profile: CrabboxProfile): WorkerLease {
  if (isTerminalState(inspect.state)) {
    throw new WorkerProviderError("Crabbox operation lease is no longer active");
  }
  if (inspect.ready !== true) {
    throw new Error("Crabbox operation lease is not ready");
  }
  if (!inspect.host || !inspect.sshUser || !inspect.sshPort || !inspect.sshKey) {
    throw new WorkerProviderError(
      "Crabbox profile provider does not expose a complete SSH worker endpoint",
    );
  }
  if (!inspect.sshHostKey) {
    throw new WorkerProviderError(
      "Crabbox inspect does not expose the SSH host key required by the worker provider contract",
    );
  }
  return {
    leaseId: inspect.id,
    ssh: {
      host: inspect.host,
      port: inspect.sshPort,
      fallbackPorts: inspect.sshFallbackPorts,
      user: inspect.sshUser,

View on GitHub (pinned to 01804a7531)

Solutions

  1. Re-inspect: `crabbox inspect --provider <p> --id <id> --json | jq .ready` and confirm whether it flips to true shortly.
  2. Ensure provision goes through waitForProvisionReady before lease materialization; do not short-circuit the readiness wait.
  3. If ready never becomes true, check SSH service health on the worker and the provider's readiness probe.
  4. Re-provision if the lease is stuck not-ready.
Defensive patterns

Strategy: retry

Try / catch

try {
  await provider.provision(profile, operationId);
} catch (error) {
  if (error instanceof Error && error.message.includes("lease is not ready")) {
    // transient — re-provision after confirming SSH service health on the worker
  }
  throw error;
}

Prevention

When it happens

Trigger: leaseFromInspect called with inspect.ready being undefined, false, or any non-true value. At provision this is normally guarded by waitForProvisionReady polling until ready===true, so this fires when leaseFromInspect is reached with ready !== true — typically a race or a caller bypassing the readiness wait. Triggered at crabbox-worker-provider.ts:326-328.

Common situations: waitForProvisionReady's loop exited because state became unusable (handled separately) but leaseFromInspect was still called; a direct call to leaseFromInspect skipping the readiness poll; inspect.ready regressed from true to false between the last poll and leaseFromInspect (SSH flap).

Related errors


AI-assisted analysis of openclaw/openclaw@01804a7531 (2026-08-12). Data as JSON: /api/errors/4f7ec5e0f22e6e48. Report an issue: GitHub.