mastra-ai/mastra · error

Platform GitHub event polling interval must be a positive nu

Error message

Platform GitHub event polling interval must be a positive number.

What it means

Thrown from the PlatformGithubEventWorker constructor (event-worker.ts:150) when the config.intervalMs option is provided but is not a finite number greater than 0 (NaN, 0, negative, Infinity). The worker polls GitHub events on this interval, so a non-positive value would create a tight loop or a broken timer; construction fails fast instead.

Source

Thrown at mastracode/factory/src/integrations/platform/github/event-worker.ts:150

  #lastIssueReconcileAt = 0;
  #settings: PlatformGithubEventWorkerSettings = { version: 1, repositories: {} };

  constructor(config: PlatformGithubEventWorkerConfig) {
    super();
    this.#client = config.client;
    this.#controller = config.controller;
    this.#github = config.github;
    this.#storage = config.storage;
    this.#ingestFactoryEvent = config.ingestFactoryEvent;
    this.#reconcileFactoryState = config.reconcileFactoryState;
    this.#reconcileIssuesFactoryState = config.reconcileIssuesFactoryState;
    this.#pollEventsEnabled = config.pollEventsEnabled ?? true;
    const legacyReconcileIntervalMs = config.reconcileIntervalMs ?? DEFAULT_RECONCILE_INTERVAL_MS;
    this.#pullRequestReconcileIntervalMs = config.pullRequestReconcileIntervalMs ?? legacyReconcileIntervalMs;
    this.#issueReconcileIntervalMs = config.issueReconcileIntervalMs ?? legacyReconcileIntervalMs;
    this.#intervalMs = config.intervalMs ?? DEFAULT_POLL_INTERVAL_MS;
    if (!Number.isFinite(this.#intervalMs) || this.#intervalMs <= 0) {
      throw new Error('Platform GitHub event polling interval must be a positive number.');
    }
    if (!Number.isFinite(this.#pullRequestReconcileIntervalMs) || this.#pullRequestReconcileIntervalMs <= 0) {
      throw new Error('Platform GitHub pull request reconcile interval must be a positive number.');
    }
    if (!Number.isFinite(this.#issueReconcileIntervalMs) || this.#issueReconcileIntervalMs <= 0) {
      throw new Error('Platform GitHub issue reconcile interval must be a positive number.');
    }
    this.#leaseTtlMs = Math.max(
      MIN_LEASE_TTL_MS,
      Math.min(this.#intervalMs, this.#pullRequestReconcileIntervalMs, this.#issueReconcileIntervalMs) * 3,
    );
    this.#now = config.now ?? Date.now;
    this.#dispatch = config.dispatch ?? dispatchGithubWebhook;
    this.#sourceControl = config.sourceControl;
  }

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

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Set config.intervalMs to a positive finite number of milliseconds (e.g. 30000).
  2. If unset is intended, omit intervalMs entirely so the DEFAULT_POLL_INTERVAL_MS is used.
  3. Validate env parsing: use a fallback like Number.isFinite(v) && v > 0 ? v : undefined before passing to the constructor.
  4. To disable polling, use the dedicated config.pollEventsEnabled flag set to false, not intervalMs: 0.

Example fix

// before
const worker = new PlatformGithubEventWorker({
  intervalMs: Number(process.env.GITHUB_POLL_INTERVAL_MS), // NaN when unset
});

// after
const raw = Number(process.env.GITHUB_POLL_INTERVAL_MS);
const worker = new PlatformGithubEventWorker({
  ...(Number.isFinite(raw) && raw > 0 ? { intervalMs: raw } : {}),
});
Defensive patterns

Strategy: validation

Validate before calling

function toPositiveInt(value: unknown, fallback?: number): number | undefined {
  const n = Number(value);
  if (Number.isFinite(n) && n > 0) return n;
  if (fallback !== undefined) return fallback;
  throw new TypeError(`intervalMs must be a positive finite number, got ${String(value)}`);
}
const intervalMs = process.env.GITHUB_POLL_INTERVAL_MS
  ? toPositiveInt(process.env.GITHUB_POLL_INTERVAL_MS)
  : undefined;

Type guard

function isPositiveFiniteMs(v: unknown): v is number {
  return typeof v === 'number' && Number.isFinite(v) && v > 0;
}

Try / catch

try {
  const worker = new PlatformGithubEventWorker(config);
} catch (err) {
  if (err instanceof Error && err.message.includes('polling interval')) {
    logger.error('Bad intervalMs in worker config; using default', { intervalMs: config.intervalMs });
  }
  throw err;
}

Prevention

When it happens

Trigger: new PlatformGithubEventWorker({ ..., intervalMs: 0 }), intervalMs: -1000, intervalMs: NaN (e.g. Number(process.env.POLL_MS) on an empty/unset env var), or intervalMs: Infinity.

Common situations: Missing or empty environment variable parsed with Number() yielding NaN; a YAML/JSON config where the value was written as a string and coerced incorrectly; someone 'disabling' polling by setting the interval to 0; unit tests passing placeholder values.

Understand the failure class

Background: "Invalid configuration value" and "Unsupported/Unknown setting value" errors: why libraries reject your config strings, numbers, and types — this error's family across 30 libraries.

Related errors


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