Skip to content

fix(detection): stop framework detection OOM on large repos - #970

Draft
posthog[bot] wants to merge 1 commit into
mainfrom
posthog-code/fix-detection-oom-node-modules
Draft

fix(detection): stop framework detection OOM on large repos#970
posthog[bot] wants to merge 1 commit into
mainfrom
posthog-code/fix-detection-oom-node-modules

Conversation

@posthog

@posthog posthog Bot commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

Problem

Running npx @posthog/wizard@latest could crash with a fatal JavaScript heap out-of-memory error during framework detection — before any setup work started, so affected users had no way to install PostHog and no workaround. Because the process died mid-detection it never self-reported, showing up as silent onboarding drop-off rather than a captured error.

The root cause: on every run, detection loops over all registered frameworks and calls each detect() predicate unconditionally. The Python, Swift, and Cloudflare detectors ran recursive ** globs whose ignore lists covered only venv/build-artifact dirs — not node_modules or .git. On a large JS/TS repo, fast-glob buffered the entire node_modules tree (often 100K+ entries) into memory just to check whether the project was Python. The Promise.race timeout in framework.ts didn't abort the walk either — it only stopped awaiting it, so memory kept climbing in the background until the heap died. Scoped to projects with big filesystem trees, so a subset of runs rather than all.

Why: The wizard is PostHog's primary onboarding entry point, and this was a hard crash of the core flow for users with large repos.

Changes

  • Add a shared DETECTION_IGNORE_PATTERNS (node_modules, .git, dist, build, venv/.venv/env/.env, __pycache__) and apply it to the Python, Swift, and Cloudflare detectors — matching the ignore discipline the Django/Flask/FastAPI detectors already follow. This is the definitive fix for the OOM.
  • Wire the detection timeout in framework.ts to an AbortController and route the heavy recursive globs through a new globWithAbort helper that streams the walk and destroy()s it on abort, so a runaway detection actually stops reading the filesystem instead of leaking memory after the race resolves.

Test plan

  • New src/lib/detection/__tests__/glob.test.ts: covers the ignore constant, globWithAbort (pass-through, ignore list, pre-aborted, abort mid-walk), and regression tests that Python/Swift detection no longer walks into node_modules.
  • Full unit suite green (1575 tests), tsc adds no new type errors, prettier + eslint clean on changed files.

Created with PostHog Code from this inbox report.

Framework detection ran recursive `**` globs before any agent work, and the
Python/Swift/Cloudflare detectors only ignored venv/build-artifact dirs — not
node_modules or .git. On large JS/TS repos fast-glob buffered the whole
node_modules tree (100K+ entries) into memory just to check whether the project
was Python, crashing `npx @posthog/wizard` with a JS heap OOM during detection,
before any setup could happen.

- Add a shared DETECTION_IGNORE_PATTERNS (node_modules, .git, dist, build,
  venv/.venv/env/.env, __pycache__) and apply it to the Python, Swift, and
  Cloudflare detectors, matching the discipline the Django/Flask/FastAPI
  detectors already follow.
- Wire the detection timeout in framework.ts to an AbortController and stream
  the heavy globs via globWithAbort, so a runaway walk actually stops reading
  the filesystem instead of leaking memory after Promise.race resolves.

Generated-By: PostHog Code
Task-Id: 61aad81a-0f26-44b6-b42b-62b4cc64597b
@github-actions

Copy link
Copy Markdown

🧙 Wizard CI

Run the Wizard CI and test your changes against wizard-workbench example apps by replying with a GitHub comment using one of the following commands:

Test all apps:

  • /wizard-ci all

Test all apps in a directory:

  • /wizard-ci basic-integration
  • /wizard-ci mcp-analytics
  • /wizard-ci revenue

Test an individual app:

  • /wizard-ci basic-integration/android
  • /wizard-ci basic-integration/angular
  • /wizard-ci basic-integration/astro
Show more apps
  • /wizard-ci basic-integration/django
  • /wizard-ci basic-integration/fastapi
  • /wizard-ci basic-integration/flask
  • /wizard-ci basic-integration/javascript-node
  • /wizard-ci basic-integration/javascript-web
  • /wizard-ci basic-integration/laravel
  • /wizard-ci basic-integration/next-js
  • /wizard-ci basic-integration/nuxt
  • /wizard-ci basic-integration/python
  • /wizard-ci basic-integration/rails
  • /wizard-ci basic-integration/react-native
  • /wizard-ci basic-integration/react-router
  • /wizard-ci basic-integration/sveltekit
  • /wizard-ci basic-integration/swift
  • /wizard-ci basic-integration/tanstack-router
  • /wizard-ci basic-integration/tanstack-start
  • /wizard-ci basic-integration/vue
  • /wizard-ci mcp-analytics/custom-dispatcher
  • /wizard-ci mcp-analytics/typescript-sdk
  • /wizard-ci revenue/stripe

Results will be posted here when complete.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants