Skip to content

fix(detection): stop strict JSON.parse from breaking project scoping - #1035

Draft
posthog[bot] wants to merge 2 commits into
mainfrom
posthog-code/tolerant-detection-json-parsing
Draft

fix(detection): stop strict JSON.parse from breaking project scoping#1035
posthog[bot] wants to merge 2 commits into
mainfrom
posthog-code/tolerant-detection-json-parsing

Conversation

@posthog

@posthog posthog Bot commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

Problem

Two detection paths handed raw, untrusted text straight to a strict JSON.parse, and both threw SyntaxErrors in production.

The consequential one is extractJson in src/lib/detection/agentic.ts: it sliced the detection agent's output from the first { to the last }. When the agent's single-line JSON was cut off mid-projects, that last } belonged to a nested project object, so the slice ended inside the array and the parse blew up. The error propagated out of scopeInstallDirToProject, which then gave up on narrowing the target — a headless monorepo run integrated against the un-narrowed install dir, i.e. the wrong directory.

The other is addNpmDeps in src/lib/warehouse-sources/detect.ts, which strict-parsed every file named package.json the project walk found. A JSONC-style manifest (comments, trailing comma) threw, the project silently lost all its npm signals, and we got error-tracking noise for an expected input.

Changes

  • extractJson now finds the object by balancing braces and brackets from the opening { (string- and escape-aware) instead of reaching for the last }. An unbalanced tail is reported as truncation, and a failed parse of a balanced slice as malformed JSON — both via a new AgentOutputParseError with a readable message rather than a raw SyntaxError. As a bonus this also handles trailing prose that happens to contain a }.
  • scopeInstallDirToProject records an AgentOutputParseError through the usual agentic detection outcome event but no longer routes it to captureException — unparseable agent output is expected input, not a wizard bug.
  • addNpmDeps parses with the jsonc-parser the repo already depends on (comments + trailing commas tolerated) and drops the captureException for this case.

Note: a truncated scan still degrades to "continue with the install dir as-is"; salvaging complete projects out of a partial array is deliberately out of scope here. This change makes the failure legible, stops it from being an exception, and removes the last-} overreach that caused it in recoverable cases.

Test plan

pnpm build && pnpm test && pnpm fix — 118 files / 1683 tests pass. New coverage:

  • src/lib/detection/__tests__/agentic.test.tsextractJson over bare / fenced / prose-wrapped output, trailing stray brace, truncated mid-projects output, malformed JSON and no-object input.
  • src/lib/detection/__tests__/project-scope.test.ts — truncated agent output fires the error outcome with the message and does not call captureException.
  • src/lib/warehouse-sources/__tests__/detect.test.ts — a package.json with comments and a trailing comma still yields its npm signals; unparseable and non-object manifests are skipped without throwing.

LLM context

Authored by PostHog Code from the linked inbox report.


Created with PostHog Desktop from this inbox report.

Two detection paths handed raw, untrusted text to a strict JSON.parse.

extractJson sliced the detection agent's output from the first `{` to the
LAST `}`, so truncated single-line JSON ended inside the `projects` array
and threw a raw SyntaxError. That propagated out of
scopeInstallDirToProject, which then abandoned project scoping — a
headless monorepo run integrated against the un-narrowed install dir. It
now balances braces and brackets from the opening `{` and reports
truncated / malformed output as an AgentOutputParseError with a clear
message, which project-scope records as an outcome without also raising
an exception.

addNpmDeps strict-parsed every file named package.json the project walk
found, so a JSONC-style manifest lost all its npm signals (and generated
error-tracking noise). It now uses the jsonc-parser the repo already
depends on, tolerating comments and trailing commas.

Adds coverage for both: extractJson (fenced/prose/trailing-brace/
truncated/malformed), the truncated-output path through
scopeInstallDirToProject, and the malformed-package.json skip.

Generated-By: PostHog Code
Task-Id: 0b01b412-c260-469c-9a1f-84fd14e209f1
@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
  • /wizard-ci self-driving

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
  • /wizard-ci self-driving/astro
  • /wizard-ci self-driving/fastapi
  • /wizard-ci self-driving/nuxt
  • /wizard-ci self-driving/react-router
  • /wizard-ci self-driving/sveltekit

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.

1 participant