mastra-ai/mastra · error

GitHub installation ${connection.installationId} was not fou

Error message

GitHub installation ${connection.installationId} was not found

What it means

The connection tied to the repository link references a GitHub App installation (installationId). If storage.installations.get finds no such installation in the org, createWorkspaceFactory throws because token minting for the sandbox requires the installation.

Source

Thrown at mastracode/factory/src/workspace.ts:297

      throw new Error('GitHub and a sandbox callback are required to create a Factory session workspace');
    }
    const createSessionSandboxInstance = sandboxConfig;

    const storage = github.sourceControlStorage;
    const projectRepository = await storage.projectRepositories.get({
      orgId: session.orgId,
      id: session.projectRepositoryId,
    });
    if (!projectRepository) throw new Error(`Repository link ${session.projectRepositoryId} was not found`);
    // The remaining reads only depend on the repository link — issue them in
    // parallel instead of paying four sequential storage round-trips.
    const [connection, repository] = await Promise.all([
      storage.connections.get({ orgId: session.orgId, id: projectRepository.connectionId }),
      storage.repositories.get({ orgId: session.orgId, id: projectRepository.repositoryId }),
    ]);
    if (!connection || !repository) throw new Error(`Repository link ${session.projectRepositoryId} is incomplete`);
    const installation = await storage.installations.get({ orgId: session.orgId, id: connection.installationId });
    if (!installation) throw new Error(`GitHub installation ${connection.installationId} was not found`);
    const repoFullName = repository.slug;

    // Construct (or fetch) the session's memoized sandbox instance.
    // Construction is cheap and side-effect-free by the callback contract —
    // the VM is provisioned on `start()`, which only the materialization
    // pipeline calls. The workdir is never persisted or trusted from storage
    // or client input (the stale-workdir incident class came from reusing
    // `session.sandboxWorkdir` written under a different provider): local
    // sandboxes derive it at construction, remote sandboxes clone into the
    // VM's own home so it resolves lazily at first start.
    // `runSetupOn` references `runSessionSetup`, defined below — it is only
    // invoked during start, long after this closure fully initializes.
    const runSetupOn = (target: unknown, workdir: string) =>
      runSessionSetup(requireExec(target as WorkspaceSandbox), workdir);
    const guardedSetup = createSessionSetupHook(runSetupOn, session.id, repoFullName);
    // Composed start hook: marker-guarded repo setup, then per-start
    // credential install. It runs inside the provider's start lifecycle on
    // EVERY start (create or reconnect) — providers own lazy start

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Reinstall the GitHub App on the target org/account and re-register the installation in storage
  2. Update the connection's installationId to a valid existing installation
  3. Verify with storage.installations.get({ orgId: session.orgId, id: connection.installationId }) before resolving the session

Example fix

// before
const factory = await createWorkspaceFactory({ session }); // app uninstalled
// after
const installation = await storage.installations.get({ orgId: session.orgId, id: connection.installationId });
if (!installation) {
  await reinstallGithubAppAndRegisterInstallation(); // restores installations row
}
const factory = await createWorkspaceFactory({ session });
Defensive patterns

Strategy: validation

Validate before calling

const conn = await storage.connections.get({ orgId: session.orgId, id: link.connectionId });
if (conn) {
  const inst = await storage.installations.get({ orgId: session.orgId, id: conn.installationId });
  if (!inst) throw new Error('GitHub App installation missing; reinstall before resolving');
}

Type guard

null

Try / catch

try {
  factory = await createWorkspaceFactory({ session, user });
} catch (e) {
  if (e.message.includes('GitHub installation') && e.message.includes('was not found')) {
    // guide user to reinstall the GitHub App, then retry
  } else throw e;
}

Prevention

When it happens

Trigger: The GitHub App installation was uninstalled from the target org/account after the connection was created, or the installation row was removed from storage while its connection remains.

Common situations: An org admin uninstalling the GitHub App, installation revoked due to policy changes, or syncing connections without their installations during migrations.

Related errors


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