mastra-ai/mastra · error · Error

Deploy timed out

Error message

Deploy timed out

What it means

pollDeploy polls the deploy status every 2 seconds until the deploy reaches a terminal state or the timeout budget is exhausted. When the loop ends without a terminal status, it throws 'Deploy timed out'. The abort signal is cleaned up in finally.

Source

Thrown at packages/cli/src/commands/studio/platform-api.ts:304

          continue;
        }
        throwApiError('Poll failed', response.status, error.detail);
      }

      const { deploy } = data;

      if (deploy.status !== lastStatus) {
        lastStatus = deploy.status;
      }

      if (deploy.status === 'running' || deploy.status === 'failed' || deploy.status === 'stopped') {
        return deploy;
      }

      await new Promise(r => setTimeout(r, 2000));
    }

    throw new Error('Deploy timed out');
  } finally {
    logAbort.abort();
  }
}

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Check the deploy's status in the Mastra Studio UI — it may have completed after the CLI gave up
  2. Re-run `mastra studio deploy`; the platform deduplicates/reuses the deploy when appropriate
  3. Reduce artifact size / build time so the deploy finishes within the polling budget
  4. Check Mastra status/changelog for incidents causing stuck deploys
  5. If the CLI exposes timeout env/config (e.g. MASTRA_SKIP_PREFLIGHT-style flags, debug logs), raise the deadline or file an issue for a --timeout flag

Example fix

// before
mastra studio deploy --yes
// Error: Deploy timed out  (deploy actually finished in Studio UI)
// after: verify in Studio, then re-run or monitor there
mastra studio deploy --yes  # after backend incident resolved
Defensive patterns

Strategy: retry

Validate before calling

const deadline = Date.now() + 15 * 60 * 1000;
const status = await getDeployStatus(deployId);
if (isTerminal(status) === false && Date.now() > deadline) {
  console.warn('Deploy still in progress; check Studio UI before re-deploying.');
}

Type guard

function isTerminal(d: { status: string }): boolean {
  return ['succeeded', 'failed', 'canceled'].includes(d.status);
}

Try / catch

try {
  await pollDeploy(client, deployId);
} catch (e) {
  if (e instanceof Error && e.message === 'Deploy timed out') {
    const latest = await getDeployStatus(deployId);
    console.error(`CLI polling timed out; current server status: ${latest.status}. Check the Studio UI.`);
    process.exitCode = 4;
  } else throw e;
}

Prevention

When it happens

Trigger: The deploy record never reaches a terminal (success/failed) status within the polling window — long builds server-side, deploy stuck in 'building'/'uploading' due to a backend incident, or the poll loop's deadline being shorter than the deploy actually needs.

Common situations: Very large projects whose remote build exceeds the CLI's default timeout; API degradation where status polling returns stale data; CI jobs killed by outer timeouts interacting with this one; network flakiness making each poll slow so the wall-clock budget runs out.

Understand the failure class

Related errors


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