{"record":{"id":"03881441393607c8","repo":"mastra-ai/mastra","slug":"github-installation-connection-installationid-w","errorCode":null,"errorMessage":"GitHub installation ${connection.installationId} was not found","messagePattern":"GitHub installation (.+?) was not found","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"mastracode/factory/src/workspace.ts","lineNumber":297,"sourceCode":"      throw new Error('GitHub and a sandbox callback are required to create a Factory session workspace');\n    }\n    const createSessionSandboxInstance = sandboxConfig;\n\n    const storage = github.sourceControlStorage;\n    const projectRepository = await storage.projectRepositories.get({\n      orgId: session.orgId,\n      id: session.projectRepositoryId,\n    });\n    if (!projectRepository) throw new Error(`Repository link ${session.projectRepositoryId} was not found`);\n    // The remaining reads only depend on the repository link — issue them in\n    // parallel instead of paying four sequential storage round-trips.\n    const [connection, repository] = await Promise.all([\n      storage.connections.get({ orgId: session.orgId, id: projectRepository.connectionId }),\n      storage.repositories.get({ orgId: session.orgId, id: projectRepository.repositoryId }),\n    ]);\n    if (!connection || !repository) throw new Error(`Repository link ${session.projectRepositoryId} is incomplete`);\n    const installation = await storage.installations.get({ orgId: session.orgId, id: connection.installationId });\n    if (!installation) throw new Error(`GitHub installation ${connection.installationId} was not found`);\n    const repoFullName = repository.slug;\n\n    // Construct (or fetch) the session's memoized sandbox instance.\n    // Construction is cheap and side-effect-free by the callback contract —\n    // the VM is provisioned on `start()`, which only the materialization\n    // pipeline calls. The workdir is never persisted or trusted from storage\n    // or client input (the stale-workdir incident class came from reusing\n    // `session.sandboxWorkdir` written under a different provider): local\n    // sandboxes derive it at construction, remote sandboxes clone into the\n    // VM's own home so it resolves lazily at first start.\n    // `runSetupOn` references `runSessionSetup`, defined below — it is only\n    // invoked during start, long after this closure fully initializes.\n    const runSetupOn = (target: unknown, workdir: string) =>\n      runSessionSetup(requireExec(target as WorkspaceSandbox), workdir);\n    const guardedSetup = createSessionSetupHook(runSetupOn, session.id, repoFullName);\n    // Composed start hook: marker-guarded repo setup, then per-start\n    // credential install. It runs inside the provider's start lifecycle on\n    // EVERY start (create or reconnect) — providers own lazy start","sourceCodeStart":279,"sourceCodeEnd":315,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/mastracode/factory/src/workspace.ts#L279-L315","documentation":"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.","triggerScenarios":"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.","commonSituations":"An org admin uninstalling the GitHub App, installation revoked due to policy changes, or syncing connections without their installations during migrations.","solutions":["Reinstall the GitHub App on the target org/account and re-register the installation in storage","Update the connection's installationId to a valid existing installation","Verify with storage.installations.get({ orgId: session.orgId, id: connection.installationId }) before resolving the session"],"exampleFix":"// before\nconst factory = await createWorkspaceFactory({ session }); // app uninstalled\n// after\nconst installation = await storage.installations.get({ orgId: session.orgId, id: connection.installationId });\nif (!installation) {\n  await reinstallGithubAppAndRegisterInstallation(); // restores installations row\n}\nconst factory = await createWorkspaceFactory({ session });","handlingStrategy":"validation","validationCode":"const conn = await storage.connections.get({ orgId: session.orgId, id: link.connectionId });\nif (conn) {\n  const inst = await storage.installations.get({ orgId: session.orgId, id: conn.installationId });\n  if (!inst) throw new Error('GitHub App installation missing; reinstall before resolving');\n}","typeGuard":"null","tryCatchPattern":"try {\n  factory = await createWorkspaceFactory({ session, user });\n} catch (e) {\n  if (e.message.includes('GitHub installation') && e.message.includes('was not found')) {\n    // guide user to reinstall the GitHub App, then retry\n  } else throw e;\n}","preventionTips":["Listen for GitHub App uninstallation webhooks and clean up connections/installations","Validate installation presence when creating connections","Reinstall the GitHub App on org/account before reusing old sessions"],"tags":["github","missing-resource","installation"],"backgroundTag":"github-app-installation-missing","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}