{"record":{"id":"f4170b0e728efbb5","repo":"mastra-ai/mastra","slug":"platform-github-event-polling-interval-must-be-a-p","errorCode":null,"errorMessage":"Platform GitHub event polling interval must be a positive number.","messagePattern":"Platform GitHub event polling interval must be a positive number\\.","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"mastracode/factory/src/integrations/platform/github/event-worker.ts","lineNumber":150,"sourceCode":"  #lastIssueReconcileAt = 0;\n  #settings: PlatformGithubEventWorkerSettings = { version: 1, repositories: {} };\n\n  constructor(config: PlatformGithubEventWorkerConfig) {\n    super();\n    this.#client = config.client;\n    this.#controller = config.controller;\n    this.#github = config.github;\n    this.#storage = config.storage;\n    this.#ingestFactoryEvent = config.ingestFactoryEvent;\n    this.#reconcileFactoryState = config.reconcileFactoryState;\n    this.#reconcileIssuesFactoryState = config.reconcileIssuesFactoryState;\n    this.#pollEventsEnabled = config.pollEventsEnabled ?? true;\n    const legacyReconcileIntervalMs = config.reconcileIntervalMs ?? DEFAULT_RECONCILE_INTERVAL_MS;\n    this.#pullRequestReconcileIntervalMs = config.pullRequestReconcileIntervalMs ?? legacyReconcileIntervalMs;\n    this.#issueReconcileIntervalMs = config.issueReconcileIntervalMs ?? legacyReconcileIntervalMs;\n    this.#intervalMs = config.intervalMs ?? DEFAULT_POLL_INTERVAL_MS;\n    if (!Number.isFinite(this.#intervalMs) || this.#intervalMs <= 0) {\n      throw new Error('Platform GitHub event polling interval must be a positive number.');\n    }\n    if (!Number.isFinite(this.#pullRequestReconcileIntervalMs) || this.#pullRequestReconcileIntervalMs <= 0) {\n      throw new Error('Platform GitHub pull request reconcile interval must be a positive number.');\n    }\n    if (!Number.isFinite(this.#issueReconcileIntervalMs) || this.#issueReconcileIntervalMs <= 0) {\n      throw new Error('Platform GitHub issue reconcile interval must be a positive number.');\n    }\n    this.#leaseTtlMs = Math.max(\n      MIN_LEASE_TTL_MS,\n      Math.min(this.#intervalMs, this.#pullRequestReconcileIntervalMs, this.#issueReconcileIntervalMs) * 3,\n    );\n    this.#now = config.now ?? Date.now;\n    this.#dispatch = config.dispatch ?? dispatchGithubWebhook;\n    this.#sourceControl = config.sourceControl;\n  }\n\n  async init(deps: WorkerDeps): Promise<void> {\n    await super.init(deps);","sourceCodeStart":132,"sourceCodeEnd":168,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/mastracode/factory/src/integrations/platform/github/event-worker.ts#L132-L168","documentation":"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.","triggerScenarios":"new PlatformGithubEventWorker({ ..., intervalMs: 0 }), intervalMs: -1000, intervalMs: NaN (e.g. Number(process.env.POLL_MS) on an empty/unset env var), or intervalMs: Infinity.","commonSituations":"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.","solutions":["Set config.intervalMs to a positive finite number of milliseconds (e.g. 30000).","If unset is intended, omit intervalMs entirely so the DEFAULT_POLL_INTERVAL_MS is used.","Validate env parsing: use a fallback like Number.isFinite(v) && v > 0 ? v : undefined before passing to the constructor.","To disable polling, use the dedicated config.pollEventsEnabled flag set to false, not intervalMs: 0."],"exampleFix":"// before\nconst worker = new PlatformGithubEventWorker({\n  intervalMs: Number(process.env.GITHUB_POLL_INTERVAL_MS), // NaN when unset\n});\n\n// after\nconst raw = Number(process.env.GITHUB_POLL_INTERVAL_MS);\nconst worker = new PlatformGithubEventWorker({\n  ...(Number.isFinite(raw) && raw > 0 ? { intervalMs: raw } : {}),\n});","handlingStrategy":"validation","validationCode":"function toPositiveInt(value: unknown, fallback?: number): number | undefined {\n  const n = Number(value);\n  if (Number.isFinite(n) && n > 0) return n;\n  if (fallback !== undefined) return fallback;\n  throw new TypeError(`intervalMs must be a positive finite number, got ${String(value)}`);\n}\nconst intervalMs = process.env.GITHUB_POLL_INTERVAL_MS\n  ? toPositiveInt(process.env.GITHUB_POLL_INTERVAL_MS)\n  : undefined;","typeGuard":"function isPositiveFiniteMs(v: unknown): v is number {\n  return typeof v === 'number' && Number.isFinite(v) && v > 0;\n}","tryCatchPattern":"try {\n  const worker = new PlatformGithubEventWorker(config);\n} catch (err) {\n  if (err instanceof Error && err.message.includes('polling interval')) {\n    logger.error('Bad intervalMs in worker config; using default', { intervalMs: config.intervalMs });\n  }\n  throw err;\n}","preventionTips":["Never pass Number(env) directly; check Number.isFinite and > 0 first.","Omit intervalMs to use the library default instead of guessing a value.","Use pollEventsEnabled: false to disable polling, not intervalMs: 0.","Validate worker config objects with a schema (e.g. zod) at startup."],"tags":["configuration","validation","github","worker"],"backgroundTag":"invalid-configuration-value","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}