mastra-ai/mastra · error

GitHub reconcile worker requires a pull request or issue rec

Error message

GitHub reconcile worker requires a pull request or issue reconciler.

What it means

GithubReconcileWorker's constructor requires at least one reconciler: config.reconcile (pull requests) or config.reconcileIssues (issues). A worker with neither has nothing to do, so construction fails fast rather than running an idle polling loop.

Source

Thrown at mastracode/factory/src/integrations/github/reconcile-worker.ts:70

  readonly #reconcileIssues: GithubIssueReconciler | undefined;
  readonly #sourceControl: GithubReconcileRepositorySource;
  readonly #intervalMs: number;
  readonly #issueIntervalMs: number;
  readonly #leaseTtlMs: number;
  readonly #leaseOwner = randomUUID();
  readonly #now: () => number;

  #running = false;
  #timer: ReturnType<typeof setTimeout> | undefined;
  #inFlight: Promise<void> | undefined;
  #leaseProvider: LeaseProvider = NoopLeaseProvider;
  #nextPullRequestReconcileAt = 0;
  #nextIssueReconcileAt = 0;

  constructor(config: GithubReconcileWorkerConfig) {
    super();
    if (!config.reconcile && !config.reconcileIssues) {
      throw new Error('GitHub reconcile worker requires a pull request or issue reconciler.');
    }
    this.#reconcile = config.reconcile;
    this.#reconcileIssues = config.reconcileIssues;
    this.#sourceControl = config.sourceControl;
    this.#intervalMs = config.intervalMs ?? DEFAULT_GITHUB_RECONCILE_INTERVAL_MS;
    this.#issueIntervalMs = config.issueIntervalMs ?? this.#intervalMs;
    if (!Number.isFinite(this.#intervalMs) || this.#intervalMs <= 0) {
      throw new Error('GitHub pull request reconcile interval must be a positive number.');
    }
    if (!Number.isFinite(this.#issueIntervalMs) || this.#issueIntervalMs <= 0) {
      throw new Error('GitHub issue reconcile interval must be a positive number.');
    }
    this.#leaseTtlMs = Math.max(MIN_LEASE_TTL_MS, Math.min(this.#intervalMs, this.#issueIntervalMs) * 3);
    this.#now = config.now ?? Date.now;
  }

  async init(deps: WorkerDeps): Promise<void> {
    await super.init(deps);

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Pass at least one of reconcile or reconcileIssues callbacks in the config.
  2. If you only sync issues, set reconcileIssues; if only PRs, set reconcile.
  3. Check the config construction code for conditional omission or property-name typos.
  4. If you truly need no reconciliation, don't construct the worker at all.

Example fix

// before
new GithubReconcileWorker({ sourceControl });
// after
new GithubReconcileWorker({ sourceControl, reconcile: reconcilePullRequests });
Defensive patterns

Strategy: validation

Validate before calling

if (!config.reconcile && !config.reconcileIssues) throw new Error('GithubReconcileWorker needs at least one of reconcile / reconcileIssues');

Type guard

function isWorkerConfig(c: GithubReconcileWorkerConfig): boolean {
  return typeof c.reconcile === 'function' || typeof c.reconcileIssues === 'function';
}

Try / catch

try {
  worker = new GithubReconcileWorker(config);
} catch (e) {
  if ((e as Error).message.includes('requires a pull request or issue reconciler')) {
    log.error('worker config has no reconcilers', config);
  }
  throw e;
}

Prevention

When it happens

Trigger: new GithubReconcileWorker({ sourceControl, intervalMs }) with both reconcile and reconcileIssues omitted or explicitly set to undefined.

Common situations: Partial config after a refactor adding the issues option; config object built conditionally where both branches were skipped; typos like reconciler vs reconcile.

Understand the failure class

Background: "X is required", "must be set", "cannot be empty": the missing-required-config error family, from Vertex AI project/location to WeChat keys — this error's family across 18 libraries.

Related errors


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