mastra-ai/mastra · error

Failed to load repository settings (${res.status})

Error message

Failed to load repository settings (${res.status})

What it means

fetchRepositorySettings in mastracode/factory-ui/src/ui/domains/workspaces/services/github.ts throws this when the GET to `${baseUrl}/web/github/projects/${projectRepositoryId}/settings` returns a non-OK HTTP status. The status code is embedded in the message so developers can distinguish 404 (unknown repository id) from 401/403 (auth) or 500 (server fault). The raw fetch response body is discarded, so server-side error details are not surfaced.

Source

Thrown at mastracode/factory-ui/src/ui/domains/workspaces/services/github.ts:530

   * Shell command run inside every freshly created worktree before any agent
   * execution (e.g. `pnpm i && pnpm build`). `null` when no setup step is
   * configured.
   */
  setupCommand: string | null;
  /** Best-effort shell command run before a session workspace is retired. */
  teardownCommand: string | null;
}

/** Read a repository's worktree lifecycle settings. */
export async function fetchRepositorySettings(
  baseUrl: string,
  projectRepositoryId: string,
): Promise<RepositorySettings> {
  const res = await fetch(`${baseUrl}/web/github/projects/${encodeURIComponent(projectRepositoryId)}/settings`, {
    headers: { Accept: 'application/json' },
    credentials: 'include',
  });
  if (!res.ok) throw new Error(`Failed to load repository settings (${res.status})`);
  return (await res.json()) as RepositorySettings;
}

/** Persist a repository's lifecycle commands. Pass `null` (or blank) to clear one. */
export async function saveRepositorySettings(
  baseUrl: string,
  projectRepositoryId: string,
  settings: RepositorySettings,
): Promise<RepositorySettings> {
  return postRepositoryGitOp<RepositorySettings>(baseUrl, projectRepositoryId, 'settings', settings);
}

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Log the status from the message and call the same URL manually (with credentials: 'include') to inspect the response body for the real server error.
  2. Verify projectRepositoryId is current — re-fetch the repository list and confirm the id still exists (404 usually means stale id).
  3. If 401/403, re-authenticate / refresh the session cookie and confirm the user has access to the project.
  4. Retry on transient statuses (502/503/504) — React Query's retry may already handle this; check retry config in useRepositorySettingsQuery.

Example fix

// before: server error body is lost
if (!res.ok) throw new Error(`Failed to load repository settings (${res.status})`);
// after: include server-provided detail
type SettingsError = { error?: string };
const errBody: SettingsError = res.ok ? {} : await res.clone().json().catch(() => ({}));
if (!res.ok) throw new Error(errBody.error ?? `Failed to load repository settings (${res.status})`);
Defensive patterns

Strategy: try-catch

Validate before calling

// no client-side pre-check can guarantee the HTTP result, but validate inputs and auth up front
if (!projectRepositoryId) throw new Error('projectRepositoryId is required');
const authed = document.cookie.includes('session='); // heuristic: ensure session cookie present
if (!authed) await refreshSession();

Type guard

function isRepositorySettings(v: unknown): v is RepositorySettings {
  return typeof v === 'object' && v !== null && 'id' in v;
}

Try / catch

try {
  const settings = await fetchRepositorySettings(baseUrl, id);
} catch (err) {
  const msg = err instanceof Error ? err.message : String(err);
  const status = Number(msg.match(/\((\d{3})\)/)?.[1] ?? 0);
  if (status === 404) showEmptySettings();
  else if (status === 401 || status === 403) redirectToLogin();
  else showToast('Could not load settings; retrying...');
}

Prevention

When it happens

Trigger: Any response with res.ok === false from the settings endpoint: nonexistent or stale projectRepositoryId (404), expired/missing session cookie (401), insufficient permissions on the GitHub-backed project (403), or backend failure (500). It fires for every non-2xx; 404 is NOT tolerated here unlike deleteUserSession.

Common situations: React Query's useRepositorySettingsQuery renders a repository settings panel for a repository that was deleted or whose id changed after a re-sync; the user's session cookie expired mid-tab; a proxy/ingress returns 502; the workspace backend restarted with a data migration that invalidated old project repository ids.

Understand the failure class

Background: 'Something went wrong' / 'Request failed (500)' / 'HTTP error! status: 404' — what failed HTTP requests actually mean and how to find the real cause — 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/9b3c292b8e0a6160. Report an issue: GitHub.