{"record":{"id":"cf0eda6969165c11","repo":"mastra-ai/mastra","slug":"githubreconcileworker-call-init-before-start","errorCode":null,"errorMessage":"GithubReconcileWorker: call init() before start()","messagePattern":"GithubReconcileWorker: call init\\(\\) before start\\(\\)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"mastracode/factory/src/integrations/github/reconcile-worker.ts","lineNumber":94,"sourceCode":"    this.#issueIntervalMs = config.issueIntervalMs ?? this.#intervalMs;\n    if (!Number.isFinite(this.#intervalMs) || this.#intervalMs <= 0) {\n      throw new Error('GitHub pull request reconcile interval must be a positive number.');\n    }\n    if (!Number.isFinite(this.#issueIntervalMs) || this.#issueIntervalMs <= 0) {\n      throw new Error('GitHub issue reconcile interval must be a positive number.');\n    }\n    this.#leaseTtlMs = Math.max(MIN_LEASE_TTL_MS, Math.min(this.#intervalMs, this.#issueIntervalMs) * 3);\n    this.#now = config.now ?? Date.now;\n  }\n\n  async init(deps: WorkerDeps): Promise<void> {\n    await super.init(deps);\n    this.#leaseProvider = getLeaseProvider(deps.pubsub);\n  }\n\n  async start(): Promise<void> {\n    if (this.#running) return;\n    if (!this.deps) throw new Error('GithubReconcileWorker: call init() before start()');\n    this.#running = true;\n    this.deps.logger.info('GitHub reconcile worker started', {\n      pullRequestIntervalMs: this.#reconcile ? this.#intervalMs : undefined,\n      issueIntervalMs: this.#reconcileIssues ? this.#issueIntervalMs : undefined,\n    });\n    // Sweep on boot: a restart is exactly when webhooks were most likely missed.\n    this.#schedule(0);\n  }\n\n  async stop(): Promise<void> {\n    if (!this.#running) return;\n    this.#running = false;\n    if (this.#timer) clearTimeout(this.#timer);\n    this.#timer = undefined;\n    await this.#inFlight;\n  }\n\n  get isRunning(): boolean {","sourceCodeStart":76,"sourceCodeEnd":112,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/mastracode/factory/src/integrations/github/reconcile-worker.ts#L76-L112","documentation":"GithubReconcileWorker.start() requires init(deps) to have been called first, since start() reads this.deps (logger, pubsub) to run boot sweeps and scheduling. If start() is called before init() and the worker isn't already running, it throws this explicit lifecycle error instead of failing later with an opaque undefined-deps crash.","triggerScenarios":"Calling `worker.start()` directly after `new GithubReconcileWorker(...)` without a preceding `await worker.init(deps)`; or calling start() on a second instance that never got init (a first instance with init returns early via `if (this.#running) return;`).","commonSituations":"Wiring the worker in a DI/bootstrap file where construction and start happen in different modules and the init step was dropped during refactoring; tests instantiating the worker and calling start() without fixture deps.","solutions":["Call `await worker.init(deps)` (with logger and pubsub) before `await worker.start()`.","Check startup ordering so the module that starts the worker also performs init.","In tests, use the same fixture/deps helper used elsewhere to init before start."],"exampleFix":"// before\nconst worker = new GithubReconcileWorker(config);\nawait worker.start();\n// after\nconst worker = new GithubReconcileWorker(config);\nawait worker.init({ logger, pubsub });\nawait worker.start();","handlingStrategy":"validation","validationCode":"if (!worker.isInitialized?.() && !workerHasDeps) await worker.init(deps); // or track init yourself\nlet inited = false;\nasync function startWorker(w, deps) { if (!inited) { await w.init(deps); inited = true; } await w.start(); }","typeGuard":"function isInitialized(w: GithubReconcileWorker): boolean { return 'deps' in w && (w as { deps?: unknown }).deps !== undefined; }","tryCatchPattern":"try {\n  await worker.start();\n} catch (err) {\n  if (err instanceof Error && err.message.includes('call init() before start()')) {\n    await worker.init(deps);\n    await worker.start();\n  } else throw err;\n}","preventionTips":["Wrap construction+init+start in one bootstrap function so ordering can't drift.","Centralize worker wiring in a single module instead of scattering start() calls.","Assert initialization in tests before invoking lifecycle methods."],"tags":["lifecycle","github","initialization-order"],"backgroundTag":"init-not-called","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}