{"record":{"id":"8947017182958e00","repo":"mastra-ai/mastra","slug":"factory-source-control-storage-is-unavailable","errorCode":null,"errorMessage":"Factory source control storage is unavailable","messagePattern":"Factory source control storage is unavailable","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"mastracode/factory/src/rules/start-coordinator.ts","lineNumber":137,"sourceCode":"  constructor(\n    controller: FactoryController,\n    storage: WorkItemsStorage,\n    transitionService?: Pick<FactoryTransitionService, 'transition'>,\n    sourceControl?: SourceControlStorageHandle,\n    memorySettings?: MemorySettingsStorage,\n    feedReader?: FactoryFeedReader,\n  ) {\n    this.#controller = controller;\n    this.#storage = storage;\n    this.#transitionService = transitionService;\n    this.#sourceControl = sourceControl;\n    this.#memorySettings = memorySettings;\n    this.#feedReader = feedReader;\n  }\n\n  async prepare(request: FactoryStartRequest): Promise<FactoryStartPreparedResult> {\n    const storage = this.#storage;\n    if (!this.#sourceControl) throw new Error('Factory source control storage is unavailable');\n    const sourceSession = await resolveSourceSession(this.#sourceControl, request);\n    const requestContext = request.requestContext ?? new RequestContext();\n    // Factory runs resolve model credentials org > user: the org's shared keys\n    // win, with the acting user's personal credentials as a fallback — a board\n    // run should never silently prefer whoever kicked it off. The flag rides\n    // the stashed user even when a caller-provided context already has one.\n    const existingUser = requestContext.get('user');\n    if (existingUser && typeof existingUser === 'object') {\n      requestContext.set('user', { ...existingUser, orgFirstCredentials: true });\n    } else {\n      requestContext.set('user', {\n        workosId: request.userId,\n        organizationId: request.orgId,\n        orgFirstCredentials: true,\n      });\n    }\n    // Sessions kicked off against third-party content (a PR under review, or\n    // any pull-request-sourced work item) get `untrustedCheckout` so the SDK","sourceCodeStart":119,"sourceCodeEnd":155,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/mastracode/factory/src/rules/start-coordinator.ts#L119-L155","documentation":"Thrown at the top of StartCoordinator.prepare when the coordinator was constructed without a source-control storage handle (this.#sourceControl is undefined). Source-control storage is mandatory to resolve the session, repository, and connection graph, so prepare fails fast instead of throwing a confusing null error deeper in resolveSourceSession.","triggerScenarios":"Instantiating the start coordinator (or the factory rules container wiring it) without providing a sourceControl storage handle — e.g. a deployment or test harness configured without source-control storage enabled — then calling prepare, prepared, preparePromptKickoff, triage, plan, first, or replay.","commonSituations":"Feature flag for factory/source-control storage disabled in the environment; DI wiring omits the storage dependency; unit tests constructing the coordinator with partial storage; self-hosted setups that skipped the storage configuration step.","solutions":["Provide the source-control storage handle when constructing the coordinator/factory so this.#sourceControl is defined.","Check environment/DI configuration that source-control storage is enabled and wired (storage adapter configured and passed to the rules factory).","Before calling start APIs, verify availability via the coordinator's `prepared` accessor and surface a clear configuration error to the operator if it is absent.","In tests, construct the coordinator with an in-memory SourceControlStorageHandle rather than omitting it."],"exampleFix":"// before\nconst coordinator = new StartCoordinator({ storage, memorySettings, feedReader }); // sourceControl missing\n\n// after\nconst coordinator = new StartCoordinator({\n  storage,\n  sourceControl: await createSourceControlStorage(config),\n  memorySettings,\n  feedReader,\n});","handlingStrategy":"fallback","validationCode":"if (!coordinator.prepared) {\n  throw new Error('Start coordinator is not configured with source-control storage; enable factory source-control storage before starting sessions.');\n}","typeGuard":"function canPrepare(coordinator: StartCoordinator): boolean {\n  return coordinator.prepared !== undefined && coordinator.prepared !== null;\n}","tryCatchPattern":"try {\n  const prepared = await coordinator.prepare(request);\n} catch (err) {\n  if (err instanceof Error && err.message === 'Factory source control storage is unavailable') {\n    console.error('Source-control storage not wired into the coordinator; fix DI/config before retrying.');\n  }\n  throw err;\n}","preventionTips":["Assert sourceControl is provided in the factory/coordinator constructor during boot or test setup.","Keep the source-control storage feature flag and its DI wiring in lockstep.","In self-hosted setups, validate storage configuration at startup, not at first API call."],"tags":["configuration","dependency-injection","storage","missing-dependency"],"backgroundTag":"missing-env-var","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}