mastra-ai/mastra · error

Authenticated user is missing a user id

Error message

Authenticated user is missing a user id

What it means

userSessionResourceId extracts the authenticated user's id from FactoryAuthState and uses it as the resourceId under which personal (non-factory) sessions live. It throws 'Authenticated user is missing a user id' when the state says a user is present but the userId field is absent (or state is undefined where a user was assumed), since session storage cannot be scoped without an id.

Source

Thrown at mastracode/factory-ui/src/ui/domains/auth/services/auth.ts:32

 * different port still reaches the Mastra server — same pattern as the shared
 * API client and `use-fs`.
 */

export interface FactoryAuthState {
  /** Whether the server has web auth configured (any provider). */
  authEnabled: boolean;
  authenticated: boolean;
  user?: { userId?: string; email?: string; name?: string; avatarUrl?: string; organizationId?: string };
  /** Active identity provider: 'workos' | 'better-auth' | custom adapter kind. */
  provider?: string;
  /** True when the provider hosts credential forms and sign-up is disabled. */
  signUpDisabled?: boolean;
}

/** The resourceId under which a user's personal (non-factory) sessions live. */
export function userSessionResourceId(state: FactoryAuthState | undefined): string {
  const userId = state?.user?.userId;
  if (!userId) throw new Error('Authenticated user is missing a user id');
  return userId;
}

/**
 * Build the hosted-login URL. `returnTo` is where the server sends the user
 * after authenticating; it defaults to the current location so contexts that
 * are not `/signin` (which would loop back to itself) round-trip in place.
 */
export function loginUrl(
  baseUrl: string,
  returnTo: string = window.location.pathname + window.location.search,
): string {
  return `${baseUrl}/auth/login?returnTo=${encodeURIComponent(returnTo)}`;
}

/** Full-page navigation to the hosted login (see `loginUrl` for `returnTo`). */
export function redirectToLogin(baseUrl: string, returnTo?: string): void {
  window.location.assign(loginUrl(baseUrl, returnTo));

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Only call userSessionResourceId after the auth state is loaded and authenticated, e.g. gate on state?.authenticated.
  2. Check the /auth state payload actually includes user.userId; fix the auth provider/endpoint if it is missing.
  3. Fall back to a loading state for personal-session UI until a userId is available.
  4. If using a custom auth integration, map the provider's subject/id into user.userId.

Example fix

// before
const resourceId = userSessionResourceId(authState); // throws if userId missing

// after
const resourceId = authState?.user?.userId
  ? userSessionResourceId(authState)
  : null; // render loading/sign-in UI instead
Defensive patterns

Strategy: type-guard

Validate before calling

if (!authState?.authenticated) return; // wait for auth to load before reading resourceId

Type guard

function hasUserId(state: FactoryAuthState | undefined): state is FactoryAuthState & { user: { userId: string } } {
  return typeof state?.user?.userId === 'string' && state.user.userId.length > 0;
}

Try / catch

let resourceId: string;
try {
  resourceId = userSessionResourceId(authState);
} catch {
  return <SignInPrompt />; // or loading spinner while auth state resolves
}

Prevention

When it happens

Trigger: Calling userSessionResourceId with state undefined (auth not yet loaded), or with a user object lacking userId — e.g. the auth endpoint returned a user payload without an id, or it is called before fetchAuthState resolves.

Common situations: Calling the helper during app boot before the auth check completes; a server-side change/upgrade altering the auth payload shape so userId is no longer populated; custom auth providers that omit userId; race conditions where session listing runs before authentication finishes.

Understand the failure class

Related errors


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