mastra-ai/mastra · error

Session is not available to the current user

Error message

Session is not available to the current user

What it means

resolveAuthorizedSession maps a workspacePath that is a Factory session id to a session record. When auth is enabled, after confirming the session exists it compares the caller's tenant (orgId/userId from deps.auth) with the session owner and throws 'Session is not available to the current user' on mismatch. This is a tenancy/ownership guard: a session exists but belongs to a different user or organization, so it must not be visible to the caller (distinct from returning null, which means no such session at all).

Solutions

  1. Confirm you are authenticated as the user who owns the session (orgId and userId must both match) — log in as that user or request access.
  2. Check the auth token/credentials: ensure they are issued for the same organization as the session.
  3. Verify the session id in workspacePath is yours (list your sessions rather than copying an id from a shared URL).
  4. If auth headers are being stripped by a proxy, fix proxy configuration so deps.auth.tenant(c) receives a valid tenant.

Example fix

// before: shared link to another user's session
GET /fs?workspacePath=<someone-elses-session-id>  // → 403-ish 'Session is not available to the current user'
// after: use your own session id
GET /fs?workspacePath=<your-own-session-id>
Defensive patterns

Strategy: try-catch

Validate before calling

// client-side: only request sessions returned by your own session list
const mySessions = await fetch('/sessions', { headers: authHeaders }).then(r => r.json());
const owns = mySessions.some(s => s.sessionId === workspacePath);
if (!owns) throw new Error('refusing request: session not owned by current user');

Type guard

function isOwnSession(
  session: { orgId: string; userId: string },
  tenant: { orgId: string; userId: string } | null,
): boolean {
  return tenant !== null && tenant.orgId === session.orgId && tenant.userId === session.userId;
}

Try / catch

try {
  const files = await fetchSessionFiles(workspacePath, threadId);
} catch (e) {
  if (e instanceof Error && e.message === 'Session is not available to the current user') {
    // treat as 403: re-authenticate with the owning org's credentials or hide the link
    return { status: 'forbidden' };
  }
  throw e;
}

Prevention

When it happens

Trigger: Requesting session filesystem routes with workspacePath set to another user's session id while authenticated; calling with an unauthenticated/no-tenant context (tenant() returns null) while the session exists; tokens issued for a different org than the one owning the session; stale credentials after the session was transferred or the user's org changed.

Common situations: Sharing a Studio/Factory URL containing a session id with a teammate; using a personal-access token from the wrong organization; a reverse proxy stripping auth headers so tenant() is null; multi-tenant environments where the client cached an old session id.

Related errors


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

Appendix: source

Thrown at mastracode/factory/src/routes/fs.ts:449

/**
 * Resolve a `workspacePath` query param as a Factory session id. Returns the
 * session when one exists and the caller owns it, `null` when no session
 * matches (the caller should fall back to local-path handling), and throws
 * when a session exists but belongs to another tenant.
 */
async function resolveAuthorizedSession(
  c: Context,
  deps: SessionFsDeps | undefined,
  workspacePath: string,
): Promise<SourceControlSession | null> {
  if (!deps) return null;
  const session = await deps.sessions.getBySessionId(workspacePath);
  if (!session) return null;
  if (deps.auth.enabled()) {
    await deps.auth.ensureUser(c);
    const tenant = deps.auth.tenant(c);
    if (!tenant || tenant.orgId !== session.orgId || tenant.userId !== session.userId) {
      throw new Error('Session is not available to the current user');
    }
  }
  return session;
}

export async function listSessionFilesystemFiles(
  filesystem: Pick<FilesystemStorage, 'listFiles'>,
  session: SourceControlSession,
  threadId: string,
): Promise<WorkspaceFilesListing> {
  const safeThreadId = threadId.trim();
  if (!safeThreadId) throw new Error('Missing required query param: threadId');

  // The turn-end capture no longer gates agent_end, so a reader refetching on
  // run completion could otherwise race it and serve the previous turn's
  // listing. Await the in-flight capture (bounded) before reading.
  await waitForPendingFilesystemCapture(session.sessionId);

View on GitHub (pinned to 75dd419e61)