mastra-ai/mastra · error

@mastra/deployer-sandbox/client is server-only: resolving a

Error message

@mastra/deployer-sandbox/client is server-only: resolving a sandbox requires provider credentials that must never reach the browser. Proxy requests through your own backend instead (see createSandboxHandler / createSandboxProxy).

What it means

The @mastra/deployer-sandbox/client module must run only on the server: resolving a sandbox requires provider credentials that would leak if executed in the browser. assertServerOnly() checks for the presence of globalThis.window and throws if the module is imported/executed in a browser environment. The library directs you to proxy through your own backend via createSandboxHandler/createSandboxProxy.

Source

Thrown at deployers/sandbox/src/client/index.ts:23

 * (e.g. VERCEL_TOKEN) — importing it in the browser would ship those
 * credentials to the client. Use the proxy/handler patterns instead so the
 * browser only ever talks to your own domain.
 */
import { supportsNetworking } from '@mastra/core/workspace';
import type { WorkspaceSandbox } from '@mastra/core/workspace';
import {
  DEFAULT_PORT,
  getInfoSafe,
  killPreviousServer,
  launchServer,
  resolveRemoteDir,
  tailServerLog,
  waitForHealthy,
} from '../shared';

function assertServerOnly(): void {
  if (typeof (globalThis as { window?: unknown }).window !== 'undefined') {
    throw new Error(
      '@mastra/deployer-sandbox/client is server-only: resolving a sandbox requires provider credentials ' +
        'that must never reach the browser. Proxy requests through your own backend instead ' +
        '(see createSandboxHandler / createSandboxProxy).',
    );
  }
}

export type DeploymentStatus = 'running' | 'stopped' | 'unknown';

export interface GetDeploymentOptions {
  /**
   * The sandbox to resolve. Provider construction is identity — e.g.
   * `new VercelSandbox({ sandboxName: 'my-preview', ports: [4111] })` resolves
   * the same sandbox from any process.
   */
  sandbox: WorkspaceSandbox;
  /** Port the Mastra server listens on. Defaults to 4111. */
  port?: number;

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Move the getDeployment() call to server code: a route handler, server action, or API route.
  2. Expose it to the browser via createSandboxHandler mounted on your backend, and call that endpoint from the client.
  3. Or use createSandboxProxy to proxy sandbox requests through your server instead of importing the client module in the browser.
  4. Verify with 'server-only' import conventions / build-time checks that the module is absent from client bundles.

Example fix

// before ('use client' component)
'use client';
import { getDeployment } from '@mastra/deployer-sandbox/client';
const dep = await getDeployment({ sandboxId: 'sbx_1' });
// after (server route + fetch)
// app/api/sandbox/route.ts: export { POST } from createSandboxHandler(...)
const res = await fetch('/api/sandbox', { method: 'POST', body: JSON.stringify({ sandboxId: 'sbx_1' }) });
Defensive patterns

Strategy: validation

Validate before calling

if (typeof window !== 'undefined') {
  throw new Error('Sandbox resolution must run server-side; call /api/sandbox instead');
}

Type guard

function isServerRuntime(): boolean {
  return typeof (globalThis as { window?: unknown }).window === 'undefined';
}

Try / catch

try {
  const dep = await getDeployment({ sandboxId });
} catch (err) {
  if ((err as Error).message.includes('server-only')) {
    // redirect to server proxy endpoint
    const res = await fetch('/api/sandbox', { method: 'POST', body: JSON.stringify({ sandboxId }) });
  } else throw err;
}

Prevention

When it happens

Trigger: Importing @mastra/deployer-sandbox/client (e.g. calling getDeployment) from client-side React/Next.js code, or bundling it into a browser bundle where window is defined at execution time.

Common situations: Calling getDeployment() inside a 'use client' component or useEffect in a Next.js app, accidentally tree-shaking the server-only marker out so the import isn't blocked at build time, or sharing one module between client and server routes.

Related errors


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