mastra-ai/mastra · error · Error

MastraAuthWorkos could not resolve a callback URL: pass `red

Error message

MastraAuthWorkos could not resolve a callback URL: pass `redirectUri` (WORKOS_REDIRECT_URI) or configure the host `publicUrl`.

What it means

MastraAuthWorkos defers redirect-URI resolution until late in setup (it may rebuild session storage and the auth service once the URI is resolved from the host's publicUrl). After that resolution step, if this.redirectUri is still empty, no OAuth callback can be constructed, so it throws with a message pointing at both configuration paths.

Source

Thrown at auth/workos/src/auth-provider.ts:786

  /**
   * One-time host initialization. Resolves the redirect URI from the host's
   * `publicUrl` (`<publicUrl>/auth/callback`) when it was not provided in the
   * options or via `WORKOS_REDIRECT_URI`.
   *
   * Fails at prepare time rather than handing WorkOS an empty redirect URI on
   * the first login (which breaks hosted login with an opaque provider error).
   */
  async init(ctx: AuthInitContext): Promise<void> {
    if (!this.redirectUri && ctx.publicUrl) {
      this.redirectUri = `${ctx.publicUrl}/auth/callback`;
      this.config.redirectUri = this.redirectUri;
      // Rebuild the session storage/auth service so they observe the resolved
      // redirect URI rather than the empty placeholder from construction.
      const storage = new WebSessionStorage(this.config);
      this.authService = new AuthService(this.config, storage, this.workos as any, sessionEncryption);
    }
    if (!this.redirectUri) {
      throw new Error(
        'MastraAuthWorkos could not resolve a callback URL: pass `redirectUri` (WORKOS_REDIRECT_URI) or configure the host `publicUrl`.',
      );
    }
  }

  // ============================================================================
  // IOrganizationsProvider Implementation
  // ============================================================================

  /**
   * Ensure the user belongs to a WorkOS organization, creating a personal org
   * on first use when they have none.
   *
   * - ≥1 membership → return the first org id (they already belong somewhere;
   *   we never auto-create when a membership exists).
   * - 0 memberships → create a personal org + membership and return its id.
   *
   * Idempotency: the create call carries `externalId = userId` and a stable

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Set WORKOS_REDIRECT_URI to your full callback URL
  2. Configure the server host publicUrl (e.g. server: { publicUrl: 'https://app.example.com' } in Mastra config) so the callback can be derived
  3. Pass redirectUri in the provider options: new MastraAuthWorkos({ ..., redirectUri: '...' })
  4. Verify with a log/config dump that the host publicUrl actually reaches init() before this guard runs

Example fix

// before
new MastraAuthWorkos({ apiKey, clientId });
// after
new MastraAuthWorkos({ apiKey, clientId, redirectUri: 'https://app.example.com/auth/callback' });
Defensive patterns

Strategy: validation

Validate before calling

function assertCallbackResolvable(opts, serverConfig) {
  const redirectUri = opts?.redirectUri ?? process.env.WORKOS_REDIRECT_URI;
  const publicUrl = serverConfig?.publicUrl;
  if (!redirectUri && !publicUrl) {
    throw new Error('MastraAuthWorkos needs WORKOS_REDIRECT_URI or server publicUrl to derive its callback URL');
  }
  return redirectUri ?? new URL('/auth/callback', publicUrl).toString();
}

Type guard

function hasResolvableCallback(opts, serverConfig) {
  return Boolean((opts?.redirectUri ?? process.env.WORKOS_REDIRECT_URI) || serverConfig?.publicUrl);
}

Try / catch

try {
  auth = new MastraAuthWorkos(options);
} catch (e) {
  if (e.message.includes('could not resolve a callback URL')) {
    throw new ConfigError('Set WORKOS_REDIRECT_URI or server.publicUrl so the OAuth callback can be built');
  }
  throw e;
}

Prevention

When it happens

Trigger: Constructing MastraAuthWorkos without options.redirectUri, without WORKOS_REDIRECT_URI, and on a host that has no publicUrl configured — the final guard in setup detects this.redirectUri is still falsy and throws.

Common situations: Local/embedded deployments where no publicUrl is set; monorepo server started without server config; migration where redirectUri config moved but env var never added; runtime host (Mastra server) not propagating publicUrl into the auth provider.

Understand the failure class

Background: "environment variable is not set" and "Missing keys in environment" errors: what missing required env var messages mean and how to fix them — this error's family across 28 libraries.

Related errors


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