Skip to content

feat(error-tracking): add the error-tracking program on the orchestrator flow - #1185

Merged
ablaszkiewicz merged 18 commits into
mainfrom
error-tracking-program
Sep 15, 2026
Merged

ablaszkiewicz merged 18 commits into
mainfrom
error-tracking-program

Conversation

@ablaszkiewicz

@ablaszkiewicz ablaszkiewicz commented Sep 1, 2026

Copy link
Copy Markdown
Contributor
CleanShot 2026-09-14 at 16 52 12

Part of a 3-PR set

Problem

Error tracking setup takes several commands today. wizard upload-source-maps also stops when the repo has no PostHog.

Changes

New command wizard error-tracking. It runs the error-tracking orchestrator flow on pi.

  • src/lib/programs/error-tracking/: a project picker after login that scopes the run to the picked project, ciPreRun for headless runs, a learn deck and error-tracking tips.
  • run-wizard and the e2e host walk the steps when a run step sets targetDir. No other program changes path.
  • posthog-cli pre-install for swift, android, react-native, flutter, go and rust. Warlock blocks npm install -g for the agent.
  • Wiring: registry, switchboard binding, intro and project picker screens, bin.ts, e2e profile.

Shared changes, for all programs:

  • pi set_env_values adds the env file to .gitignore, like the MCP facade.
  • set_env_values accepts POSTHOG_KEY when the project already reads it.
  • error-tracking and upload-source-maps share one posthog-cli pre-install helper. A failed install sends an event, not an exception.
  • tui-host initializes the local-dev settings.

Test plan

  • pnpm build && pnpm test && pnpm fix pass (2,680 tests).
  • End-to-end runs on 34 workbench fixtures, iOS simulator and Android emulator included. See Tests.

Tests

Per fixture: run the wizard, add an error trigger, build, run, and read the issue
back from PostHog. A trace that resolves to the original source shows that the
source-map upload works. Project: Test (Oli).

✅ node-webpack

node-webpack — webpack 5 + ts-loader, posthog-node already in the manifest but its key defined nowhere. The run wired @posthog/webpack-plugin with devtool: 'hidden-source-map' and deleteAfterUpload, and wrote the uploader's POSTHOG_API_KEY / POSTHOG_PROJECT_ID; release wizard-e2e-node-webpack. Triggered by node dist/index.js.
TypeError: Cannot read properties of undefined (reading 'retries') — minified lt / ct resolved to readRetryBudget / kaboom in ./src/index.ts.

Build output
INFO posthog_cli::sourcemaps::inject: injecting selection: 1 files
INFO posthog_cli::sourcemaps::source_pairs: found 1 pairs
INFO posthog_cli::api::releases: found release wizard-e2e-node-webpack@1c0d95facf6ad8bc6e4d2493dd24ff5ab5f524ee
INFO posthog_cli::sourcemaps::inject: injecting done
INFO posthog_cli::sourcemaps::plain::upload: Found 1 chunks to upload
INFO posthog_cli::api::symbol_sets: Starting upload of batch 0, 1 symbol sets
INFO posthog_cli::api::symbol_sets: Server returned 1 upload keys (0 skipped as already present)
INFO posthog_cli::api::symbol_sets: Upload summary: 1 chunk(s) uploaded, 0 skipped (0 already present, 0 too large)
INFO posthog_cli::sourcemaps::source_pairs: found 0 pairs
Stack trace
in_app  minified                source          line  resolved_name
true    dist/index.js:2:90646   ./src/index.ts  32    <anonymous>
true    dist/index.js:2:90548   ./src/index.ts  26    <anonymous>
true    dist/index.js:2:90409   ./src/index.ts  18    kaboom
true    dist/index.js:2:90380   ./src/index.ts  15    readRetryBudget

✅ node-rollup

node-rollup — Rollup 4, no TS plugin, posthog-node already in the manifest but its key defined nowhere. The run wired @posthog/rollup-plugin with deleteAfterUpload beside the existing sourcemap: true, and wrote the uploader's POSTHOG_API_KEY / POSTHOG_PROJECT_ID; release wizard-e2e-node-rollup. Triggered by node dist/index.js.
TypeError: Cannot read properties of undefined (reading 'retries') — resolved readRetryBudget -> kaboom in ../src/index.ts, with source context lines.

Build output
WARN posthog_cli::api::releases: release wizard-e2e-node-rollup@e3f6d9de70806a9ad13b9b4fab9e72b0577ea5de not found
INFO posthog_cli::api::releases: Release wizard-e2e-node-rollup@e3f6d9de70806a9ad13b9b4fab9e72b0577ea5de created successfully! 01a08669-a44d-0000-3845-63ad164ccb49
INFO posthog_cli::sourcemaps::source_pairs: found 1 pairs
INFO posthog_cli::sourcemaps::plain::upload: Found 1 chunks to upload
INFO posthog_cli::api::symbol_sets: Starting upload of batch 0, 1 symbol sets
INFO posthog_cli::api::symbol_sets: Server returned 1 upload keys (0 skipped as already present)
INFO posthog_cli::api::symbol_sets: Upload summary: 1 chunk(s) uploaded, 0 skipped (0 already present, 0 too large)
Stack trace
in_app  bundled              source              line   resolved_name
true    dist/index.js:32     ../src/index.ts     32     <anonymous>
true    dist/index.js:26:12  ../src/index.ts     25:11  kaboom
true    dist/index.js:22:19  ../src/index.ts     21:18  readRetryBudget

✅ node-rollup-typescript-plugin

node-rollup-typescript-plugin — Rollup 4 + @rollup/plugin-typescript, posthog-node already in the manifest but its key defined nowhere. The run wired @posthog/rollup-plugin after the TypeScript plugin with deleteAfterUpload, added a start script for the bundle, and wrote the uploader's POSTHOG_API_KEY / POSTHOG_PROJECT_ID; release wizard-e2e-node-rollup-typescript-plugin. Triggered by npm run start.
TypeError: Cannot read properties of undefined (reading 'tsRetryBudget') — compiled dist/index.js frames resolved back to the .ts source, with context lines.

Build output
WARN posthog_cli::api::releases: release wizard-e2e-node-rollup-typescript-plugin@dd6d4e711d9cfb84c8d4391ad38b5af3d88870e1 not found
INFO posthog_cli::api::releases: Release wizard-e2e-node-rollup-typescript-plugin@dd6d4e711d9cfb84c8d4391ad38b5af3d88870e1 created successfully! 01a08671-e694-0000-02ec-88996552e8a4
INFO posthog_cli::sourcemaps::source_pairs: found 1 pairs
INFO posthog_cli::sourcemaps::plain::upload: Found 1 chunks to upload
INFO posthog_cli::api::symbol_sets: Starting upload of batch 0, 1 symbol sets
INFO posthog_cli::api::symbol_sets: Server returned 1 upload keys (0 skipped as already present)
INFO posthog_cli::api::symbol_sets: Upload summary: 1 chunk(s) uploaded, 0 skipped (0 already present, 0 too large)
Stack trace
in_app  compiled             source              line   resolved_name
true    dist/index.js:33     ../src/index.ts     33     <anonymous>
true    dist/index.js:20:12  ../src/index.ts     26:9   kaboomTs
true    dist/index.js:17:19  ../src/index.ts     22:16  readTsRetryBudget

✅ node-raw

node-raw — plain tsc build, posthog-node already in the manifest but its key defined nowhere, while start already ran node --env-file=.env. The run installed @posthog/cli and appended a posthog-cli --dotenv-file .env sourcemap process step to build, wrote the uploader's POSTHOG_CLI_API_KEY / POSTHOG_CLI_PROJECT_ID / POSTHOG_CLI_HOST to match that flag; release node-raw. Triggered by npm run start.
TypeError: Cannot read properties of undefined (reading 'rawRetryBudget') — compiled dist/index.js frames resolved back to the .ts source, with context lines.

Build output
WARN posthog_cli::api::releases: release node-raw@e0724dfe5f69ce5130f8d533048a5a867e900677 not found
INFO posthog_cli::api::releases: Release node-raw@e0724dfe5f69ce5130f8d533048a5a867e900677 created successfully! 01a0868b-c43e-0000-4cae-d37dbd3c3b0e
INFO posthog_cli::sourcemaps::inject: injecting selection: 1 files
INFO posthog_cli::sourcemaps::source_pairs: found 1 pairs
INFO posthog_cli::sourcemaps::inject: injecting done
INFO posthog_cli::sourcemaps::plain::upload: Found 1 chunks to upload
INFO posthog_cli::api::symbol_sets: Starting upload of batch 0, 1 symbol sets
INFO posthog_cli::api::symbol_sets: Server returned 1 upload keys (0 skipped as already present)
INFO posthog_cli::api::symbol_sets: Upload summary: 1 chunk(s) uploaded, 0 skipped (0 already present, 0 too large)
Stack trace
in_app  compiled             source              line   resolved_name
true    dist/index.js:35     ../src/index.ts     35     <anonymous>
true    dist/index.js:20:12  ../src/index.ts     28:9   kaboomRaw
true    dist/index.js:17:19  ../src/index.ts     24:16  readRawRetryBudget

✅ next

next — Next.js 16 on Turbopack, posthog-js already in the manifest but its key defined nowhere. The run wired @posthog/nextjs-config via withPostHogConfig with deleteAfterUpload, and wrote NEXT_PUBLIC_POSTHOG_KEY / _HOST beside the uploader's POSTHOG_API_KEY / POSTHOG_PROJECT_ID in .env.local; release wizard-e2e-next. Clicked in Chromium against next start.
TypeError: Cannot read properties of undefined (reading 'nextRetryBudget') — minified o / i resolved to readNextRetryBudget / kaboomNext in app/KaboomButton.tsx.

Build output
✓ Compiled successfully in 749ms
INFO posthog_cli::sourcemaps::inject: injecting selection: 1 files
INFO posthog_cli::sourcemaps::source_pairs: found 35 pairs
WARN posthog_cli::api::releases: release wizard-e2e-next@4af5a7a9fc500a2f0fd04d10e6753e01bb9ef767 not found
INFO posthog_cli::api::releases: Release wizard-e2e-next@4af5a7a9fc500a2f0fd04d10e6753e01bb9ef767 created successfully! 01a0868e-fdbc-0000-2d61-92319ac4f410
INFO posthog_cli::sourcemaps::inject: injecting done
INFO posthog_cli::sourcemaps::plain::upload: Found 35 chunks to upload
INFO posthog_cli::api::symbol_sets: Starting upload of batch 0, 29 symbol sets
INFO posthog_cli::api::symbol_sets: Server returned 4 upload keys (25 skipped as already present)
INFO posthog_cli::api::symbol_sets: Upload summary: 4 chunk(s) uploaded, 25 skipped (25 already present, 0 too large)
INFO posthog_cli::sourcemaps::source_pairs: found 0 pairs
Stack trace
in_app  minified                       source                                    line  resolved_name
true    08fzpob_fp2xp.js:1:776         turbopack:///[project]/app/KaboomButton.tsx  25  <object>.onClick
true    08fzpob_fp2xp.js:1:623         turbopack:///[project]/app/KaboomButton.tsx  10  kaboomNext
true    08fzpob_fp2xp.js:1:587         turbopack:///[project]/app/KaboomButton.tsx   6  readNextRetryBudget

✅ nuxt-3-6

nuxt-3-6 — Nuxt 3.6, posthog-js already in the manifest and runtimeConfig falling back to a literal phc_placeholder, so nothing threw while events went nowhere. The run replaced that fallback with a real NUXT_PUBLIC_POSTHOG_KEY, added sourcemap.client and a nitro:build:public-assets hook running posthog-cli sourcemap inject / upload --delete-after, with the uploader's POSTHOG_CLI_* in .env; release wizard-e2e-nuxt-3-6. Clicked in Chromium against nuxt preview.
TypeError: Cannot read properties of undefined (reading 'nuxt36RetryBudget') — minified s / r resolved to readNuxt36RetryBudget / kaboomNuxt36 in components/KaboomButton.vue.

Build output
ℹ ✓ built in 979ms
✔ Client built in 984ms
ℹ ✓ built in 150ms
✔ Server built in 154ms
INFO posthog_cli::sourcemaps::inject: injecting selection: 1 files
INFO posthog_cli::sourcemaps::source_pairs: found 4 pairs
WARN posthog_cli::api::releases: release wizard-e2e-nuxt-3-6@24695cda236b0d4e440fadf245d0bd5bc3052c9e not found
INFO posthog_cli::api::releases: Release wizard-e2e-nuxt-3-6@24695cda236b0d4e440fadf245d0bd5bc3052c9e created successfully! 01a08691-39e6-0000-5ae5-8e562b426788
INFO posthog_cli::sourcemaps::inject: injecting done
INFO posthog_cli::sourcemaps::source_pairs: found 4 pairs
INFO posthog_cli::sourcemaps::plain::upload: Found 4 chunks to upload
INFO posthog_cli::api::symbol_sets: Starting upload of batch 0, 4 symbol sets
INFO posthog_cli::api::symbol_sets: Server returned 4 upload keys (0 skipped as already present)
INFO posthog_cli::api::symbol_sets: Upload summary: 4 chunk(s) uploaded, 0 skipped (0 already present, 0 too large)
INFO posthog_cli::sourcemaps::source_pairs: found 0 pairs
Stack trace
in_app  minified                  source                          line  resolved_name
true    entry.d55a2379.js:20:26894  ../components/KaboomButton.vue  21  handleClick
true    entry.d55a2379.js:20:26807  ../components/KaboomButton.vue   9  kaboomNuxt36
true    entry.d55a2379.js:20:26769  ../components/KaboomButton.vue   5  readNuxt36RetryBudget

✅ react-vite

react-vite — Vite 7 + React, posthog-js already in the manifest but its key defined nowhere. The run added build.sourcemap: 'hidden', wired @posthog/rollup-plugin through loadEnv with deleteAfterUpload, and wrote VITE_PUBLIC_POSTHOG_KEY / _HOST beside the uploader's POSTHOG_API_KEY / POSTHOG_PROJECT_ID; release wizard-e2e-react-vite. Clicked in Chromium against vite preview.
TypeError: Cannot read properties of undefined (reading 'viteRetryBudget') — one minified assets/index-DM2dbKgY.js line resolved to the exact lines of src/KaboomButton.tsx. Rollup's minified map carries no names entry for the two helpers, so those frames keep their mangled _c / gc labels while file and line are exact.

Build output
WARN posthog_cli::api::releases: release wizard-e2e-react-vite@a29f91e4039be004923ea5b3b98d8776088a9720 not found
INFO posthog_cli::api::releases: Release wizard-e2e-react-vite@a29f91e4039be004923ea5b3b98d8776088a9720 created successfully! 01a08695-fe69-0000-cc02-58bfd79aca5c
INFO posthog_cli::sourcemaps::source_pairs: found 1 pairs
INFO posthog_cli::sourcemaps::plain::upload: Found 1 chunks to upload
INFO posthog_cli::api::symbol_sets: Starting upload of batch 0, 1 symbol sets
INFO posthog_cli::api::symbol_sets: Server returned 1 upload keys (0 skipped as already present)
INFO posthog_cli::api::symbol_sets: Upload summary: 1 chunk(s) uploaded, 0 skipped (0 already present, 0 too large)
✓ built in 4.35s
Stack trace
in_app  minified                          source                    line  resolved_name
true    assets/index-DM2dbKgY.js:10:29046  ../../src/KaboomButton.tsx  23  <object>.onClick
true    assets/index-DM2dbKgY.js:10:28881  ../../src/KaboomButton.tsx   8  _c   (kaboomVite)
true    assets/index-DM2dbKgY.js:10:28844  ../../src/KaboomButton.tsx   4  gc   (readViteRetryBudget)

✅ nuxt-4-3

nuxt-4-3 — Nuxt 4.3, posthog-js already in the manifest, a client plugin reading runtimeConfig.public.posthogKey, and no runtimeConfig block defining it. The run took the @posthog/nuxt module path: sourcemap.client: 'hidden', sourcemapExcludeSources: false, a posthogConfig.sourcemaps block, and NUXT_PUBLIC_POSTHOG_KEY / _HOST beside the uploader's POSTHOG_API_KEY / POSTHOG_PROJECT_ID; release wizard-e2e-nuxt-4-3. Clicked in Chromium against nuxt preview.
TypeError: Cannot read properties of undefined (reading 'nuxt43RetryBudget') — minified s / r resolved to readNuxt43RetryBudget / kaboomNuxt43 in app/components/KaboomButton.vue.
The module and the pre-existing client plugin both call posthog.init, so the page logs You have already initialized PostHog! Re-initializing is a no-op. Capture works; the plugin's own capture_exceptions options are the part that gets dropped.

Build output
ℹ ✓ built in 885ms
✔ Client built in 891ms
ℹ ✓ built in 124ms
✔ Server built in 127ms
INFO posthog_cli::sourcemaps::inject: injecting selection: 1 files
INFO posthog_cli::sourcemaps::source_pairs: found 4 pairs
WARN posthog_cli::api::releases: release wizard-e2e-nuxt-4-3@373cfec177a561bd4b8ba76f39a8da32be40bff8 not found
INFO posthog_cli::api::releases: Release wizard-e2e-nuxt-4-3@373cfec177a561bd4b8ba76f39a8da32be40bff8 created successfully! 01a0869b-4aa6-0000-46bb-0b1f18ecaab1
INFO posthog_cli::sourcemaps::inject: injecting done
INFO posthog_cli::sourcemaps::source_pairs: found 4 pairs
INFO posthog_cli::sourcemaps::plain::upload: Found 4 chunks to upload
INFO posthog_cli::api::symbol_sets: Starting upload of batch 0, 4 symbol sets
INFO posthog_cli::api::symbol_sets: Server returned 4 upload keys (0 skipped as already present)
INFO posthog_cli::api::symbol_sets: Upload summary: 4 chunk(s) uploaded, 0 skipped (0 already present, 0 too large)
INFO posthog_cli::sourcemaps::source_pairs: found 0 pairs
INFO posthog_cli::sourcemaps::inject: injecting selection: 1 files
INFO posthog_cli::sourcemaps::source_pairs: found 13 pairs
INFO posthog_cli::api::releases: found release wizard-e2e-nuxt-4-3@373cfec177a561bd4b8ba76f39a8da32be40bff8
INFO posthog_cli::sourcemaps::inject: injecting done
INFO posthog_cli::sourcemaps::source_pairs: found 13 pairs
INFO posthog_cli::sourcemaps::plain::upload: Found 13 chunks to upload
INFO posthog_cli::api::symbol_sets: Starting upload of batch 0, 11 symbol sets
INFO posthog_cli::api::symbol_sets: Server returned 11 upload keys (0 skipped as already present)
INFO posthog_cli::api::symbol_sets: Upload summary: 11 chunk(s) uploaded, 0 skipped (0 already present, 0 too large)
INFO posthog_cli::sourcemaps::source_pairs: found 0 pairs
└  ✨ Build complete!
Stack trace
in_app  minified              source                                line  resolved_name
true    BKJIt_0u.js:6:36839   ../app/components/KaboomButton.vue      25  handleClick
true    BKJIt_0u.js:6:36701   ../app/components/KaboomButton.vue       9  kaboomNuxt43
true    BKJIt_0u.js:6:36663   ../app/components/KaboomButton.vue       5  readNuxt43RetryBudget

✅ python-flask

python-flask — Flask 3, no PostHog at all. The seed classified it as a readable-stack platform and queued no uploader subgraph: four tasks, no credentials / configure / wire-ci. The run installed posthog and python-dotenv, wired load_dotenv() with a Posthog(...) client under enable_exception_autocapture, added an @app.errorhandler(Exception) that re-raises HTTPException and calls capture_exception for the rest, and wrote POSTHOG_PROJECT_TOKEN / POSTHOG_HOST. Triggered by GET /kaboom (port 8000).
TypeError: 'NoneType' object is not subscriptable — frames arrived readable with no symbol set, which is the point of the skip.

Task graph (no uploader subgraph)
Add the PostHog SDK        completed
Initialize PostHog         completed
Capture unhandled exceptions  completed
Report the setup           completed

new deps: posthog==6.9.3, python-dotenv==1.2.1
no credentials / configure / wire-ci / test-setup task was queued
Stack trace
in_app  source        line  resolved_name
false   flask/app.py  917   full_dispatch_request
true    app.py         66   kaboom_route
true    app.py         20   kaboom_flask
true    app.py         16   read_flask_retry_budget

✅ cicd-github-actions-nested-docker-node-raw

cicd-github-actions-nested-docker-node-raw — the first fixture where wire-ci runs. GitHub Actions → a local composite action → a multi-stage docker build → an SSH deploy, so a name has to survive four hops. Verified by deriving the docker build and docker run commands from the generated YAML itself, with ${{ github.* }} resolved from a simulated runner context, then reading the trace back.
Build-time credentials: workflow secrets → action inputs → build-args for the non-secret settings, and secrets: + RUN --mount=type=secret for the personal API key, so it never lands in a layer. Release identity: the five GITHUB_* vars forwarded as ARG and ENV — docker build args are not inherited from the environment, so without this the CLI has neither them nor .git and fails the build on a runner exactly as it does locally. Runtime: the docker run -e names match the names that the source reads.
TypeError: Cannot read properties of undefined (reading 'ghaRetryBudget') — captured from the container started with the deploy step's own variable names, resolved readGhaRetryBudget -> kaboomGha in ../src/index.ts against maps uploaded during the image build.
docker build exits 0 with no SecretsUsedInArgOrEnv warning.

docker build output (command derived from action.yml, github.* simulated)
INFO posthog_cli::api::releases: found release cicd-github-actions-nested-docker-node-raw@9f8e7d6c5b4a3928170615243342516071829304
INFO posthog_cli::sourcemaps::inject: injecting done
INFO posthog_cli::sourcemaps::plain::upload: Found 1 chunks to upload
INFO posthog_cli::api::symbol_sets: Upload summary: 1 chunk(s) uploaded, 0 skipped (0 already present, 0 too large)
Stack trace
in_app  compiled             source           line   resolved_name
true    dist/index.js:32     ../src/index.ts  32     <anonymous>
true    dist/index.js:18:12  ../src/index.ts  25:9   kaboomGha
true    dist/index.js:15:19  ../src/index.ts  21:16  readGhaRetryBudget

✅ cicd-docker-node-raw

cicd-docker-node-raw — multi-stage Docker with no CI pipeline: its own header says the image is built and run by hand. The interesting case for release identity, since there is no provider to inherit git context from and .git is in .dockerignore. Verified by running the hand-written docker build and docker run the Dockerfile documents.
No GITHUB_* forwarding here — correctly, since nothing would fill it. Instead the build command carries both halves outright, --release-name plus --release-version 0.1.0 taken from the manifest, so it resolves with no git and no CI. Credentials: ARG/ENV for the non-secret settings and RUN --mount=type=secret for the personal API key.
TypeError: Cannot read properties of undefined (reading 'handRetryBudget') — captured from the container, resolved readHandRetryBudget -> kaboomHand in ../src/index.ts against maps uploaded during the image build.

docker build output (hand-run, no CI variables)
INFO posthog_cli::api::releases: found release cicd-docker-node-raw@0.1.0
INFO posthog_cli::sourcemaps::plain::upload: Found 1 chunks to upload
INFO posthog_cli::api::symbol_sets: Upload summary: 1 chunk(s) uploaded, 0 skipped (0 already present, 0 too large)
Stack trace
in_app  compiled             source           line   resolved_name
true    dist/index.js:24     ../src/index.ts  32     <anonymous>
true    dist/index.js:18:12  ../src/index.ts  25:9   kaboomHand
true    dist/index.js:15:19  ../src/index.ts  21:16  readHandRetryBudget

✅ cicd-github-actions-docker-node-raw

cicd-github-actions-docker-node-raw — GitHub Actions with the Docker build inlined in the workflow, no composite action: the same provider branch as the nested fixture, one hop shorter. Verified by deriving the docker build from the workflow's own build-push-action step with ${{ github.* }} simulated, then running the image with the deploy step's variable names.
GITHUB_* forwarded as ARG + ENV (a provider exists here, unlike the hand-built fixture), secrets: + RUN --mount=type=secret for the personal API key, build-args for the non-secret settings. Runtime names were already consistent — the source reads POSTHOG_KEY and the deploy step passes -e POSTHOG_KEY from secrets.POSTHOG_KEY — and the run left both halves alone.
TypeError: Cannot read properties of undefined (reading 'inlineRetryBudget') — resolved readInlineRetryBudget -> kaboomInline in ../src/index.ts against maps uploaded during the image build.
The project token is supplied by CI at deploy time and is not written to the local .env; the run reports it as a follow-up rather than inventing a value.

docker build output (command derived from deploy.yml, github.* simulated)
WARN posthog_cli::api::releases: release cicd-github-actions-docker-node-raw@9f8e7d6c5b4a3928170615243342516071829304 not found
INFO posthog_cli::api::releases: Release cicd-github-actions-docker-node-raw@9f8e7d6c5b4a3928170615243342516071829304 created successfully! 01a0878f-763f-0000-72d2-7376e8286e43
INFO posthog_cli::sourcemaps::plain::upload: Found 1 chunks to upload
INFO posthog_cli::api::symbol_sets: Upload summary: 1 chunk(s) uploaded, 0 skipped (0 already present, 0 too large)
Stack trace
in_app  compiled             source           line   resolved_name
true    dist/index.js:18     ../src/index.ts  22     <anonymous>
true    dist/index.js:12:12  ../src/index.ts  15:9   kaboomInline
true    dist/index.js:9:19   ../src/index.ts  11:16  readInlineRetryBudget

✅ cicd-github-actions-single-stage-docker-node-raw

cicd-github-actions-single-stage-docker-node-raw — GitHub Actions, single-stage Dockerfile. The one where secret handling actually matters: there is no throwaway build stage, so whatever the build writes into the image ships to production. Verified by deriving the docker build from the workflow, then inspecting the resulting image for the key.
The personal API key crossed the boundary on RUN --mount=type=secret and is absent from the shipped image — not in Config.Env, not in docker history, and not on the filesystem. GITHUB_* forwarded as ARG + ENV for the release identity. Note that POSTHOG_CLI_PROJECT_ID, POSTHOG_CLI_HOST and the GITHUB_* values do persist as image ENV — inherent to a single-stage build, and none of them are secrets.
TypeError: Cannot read properties of undefined (reading 'singleRetryBudget') — resolved readSingleRetryBudget -> kaboomSingle in ../src/index.ts against maps uploaded during the image build.

docker build + secret-leak checks on the shipped image
WARN posthog_cli::api::releases: release cicd-github-actions-single-stage-docker-node-raw@9f8e7d6c5b4a3928170615243342516071829304 not found
INFO posthog_cli::api::releases: Release cicd-github-actions-single-stage-docker-node-raw@9f8e7d6c5b4a3928170615243342516071829304 created successfully! 01a08797-73f0-0000-9222-6d2bff4447db
INFO posthog_cli::sourcemaps::plain::upload: Found 1 chunks to upload
INFO posthog_cli::api::symbol_sets: Upload summary: 1 chunk(s) uploaded, 0 skipped (0 already present, 0 too large)

$ docker inspect --format '{{json .Config.Env}}' | grep -c <api-key>   -> 0
$ docker history --no-trunc                        | grep -c <api-key>   -> 0
$ grep -rl <api-key> /app /root /tmp /usr/local/lib/node_modules         -> no matches
Stack trace
in_app  compiled             source           line   resolved_name
true    dist/index.js:18     ../src/index.ts  22     <anonymous>
true    dist/index.js:12:12  ../src/index.ts  15:9   kaboomSingle
true    dist/index.js:9:19   ../src/index.ts  11:16  readSingleRetryBudget

✅ rust

rust — Cargo release build, posthog-rs already in the manifest, native debug symbols rather than source maps. [profile.release] gained debug = "line-tables-only", split-debuginfo = "packed" and strip = "none"; a Makefile runs cargo build --release then posthog-cli symbol-sets upload --directory target/release --include-source, and its run target exports .env before the binary. Capture is capture_panics(true) on ErrorTrackingOptionsBuilder, passed through .error_tracking(...) and installed with posthog_rs::init_global, plus dotenvy so the token is reachable.
kaboom: rust retry budget unavailable — an uncaught panic, resolved to rust_app::kaboom_rust2 -> rust_app::read_rust_retry_budget2 with the tokio runtime frames named too.

symbol upload output (cargo release build)
INFO posthog_cli::dsym: Found 1625 source paths in DWARF (1602 after filtering)
INFO posthog_cli::dsym::source_bundle: Collected 1324 source files (31965360 bytes total)
INFO posthog_cli::dsym: Found 1625 source paths in DWARF (1602 after filtering)
INFO posthog_cli::dsym::source_bundle: Collected 1324 source files (31965360 bytes total)
INFO posthog_cli::dsym: Found 1621 source paths in DWARF (1598 after filtering)
Stack trace
in_app  resolved_name
true    rust_app::main::{closure#0}
true    rust_app::kaboom_rust2
true    rust_app::read_rust_retry_budget2
false   tokio::runtime::park::CachedParkThread::block_on::<rust_app::main::{closure#0}>

✅ cicd-github-actions-node-raw

cicd-github-actions-node-raw — GitHub Actions, no Docker: the build runs directly on the runner, output is copied to the server, and the app restarts over SSH. This is the over-application check for the release-identity rule, and it passes: no GITHUB_* forwarding at all, correct because the runner already sets them and the skill says nothing needs passing.
POSTHOG_CLI_* are scoped to the Build step's env: rather than the whole job, the personal key coming from secrets.. The deploy step passes the variable names that src/index.ts reads. capture-exceptions was skipped deliberately — init set enableExceptionAutocapture: true on the singleton and the report says so.

generated workflow (reviewed, not executed)
- name: Build
  run: npm run build
  env:
    POSTHOG_CLI_API_KEY: ${{ secrets.POSTHOG_CLI_API_KEY }}
    POSTHOG_CLI_PROJECT_ID: ${{ secrets.POSTHOG_CLI_PROJECT_ID }}
    POSTHOG_CLI_HOST: ${{ secrets.POSTHOG_CLI_HOST }}

# restart step
POSTHOG_PROJECT_TOKEN="${{ secrets.POSTHOG_PROJECT_TOKEN }}" \
POSTHOG_HOST="${{ secrets.POSTHOG_HOST }}" \
  nohup node dist/index.js > app.log 2>&1 &

✅ cicd-gitlab-node-raw

cicd-gitlab-node-raw — GitLab CI: build job compiles and uploads, deploy job rsyncs to the server and restarts over SSH. Credentials stay out of the YAML entirely — the job inherits POSTHOG_CLI_* from Settings → CI/CD → Variables, and the report names exactly which masked variables to add. No GITHUB_*-style forwarding: the job checks the repo out, so .git gives the release its commit directly.
The deploy step passes the variable names that src/index.ts reads.
The build job ran inside its declared image, node:24-alpine, and succeeded.

build job replayed in its declared image (node:24-alpine)
$ docker run node:24-alpine sh -c 'npm ci && npm run build'
> tsc && posthog-cli --dotenv-file .env sourcemap process --directory ./dist \
        --release-name cicd-gitlab-node-raw
INFO posthog_cli::api::releases: Release cicd-gitlab-node-raw@a14e0a67de02 created successfully!
INFO posthog_cli::sourcemaps::inject: injecting done
INFO posthog_cli::sourcemaps::plain::upload: Found 1 chunks to upload
INFO posthog_cli::api::symbol_sets: Upload summary: 1 chunk(s) uploaded

✅ cicd-ssh-vps-node-raw

cicd-ssh-vps-node-raw — the build happens on the VPS, over SSH: the workflow connects, pulls, and runs npm run build there. A third boundary shape, and the release-identity rule reads it correctly — GitHub's variables do not exist on the VPS, so GITHUB_ACTIONS / SHA / REF_NAME / REPOSITORY / SERVER_URL are forwarded onto the remote build command, alongside POSTHOG_CLI_*, scoped to that one command rather than exported for the whole session.
The restart line passes the variable names that src/index.ts reads.

generated deploy step (reviewed, not executed)
git pull --ff-only origin main
npm ci
POSTHOG_CLI_API_KEY="${{ secrets.POSTHOG_CLI_API_KEY }}" \
POSTHOG_CLI_PROJECT_ID="${{ secrets.POSTHOG_CLI_PROJECT_ID }}" \
POSTHOG_CLI_HOST="${{ secrets.POSTHOG_CLI_HOST }}" \
GITHUB_ACTIONS=true \
GITHUB_SHA="${{ github.sha }}" \
GITHUB_REF_NAME="${{ github.ref_name }}" \
GITHUB_REPOSITORY="${{ github.repository }}" \
GITHUB_SERVER_URL="${{ github.server_url }}" \
  npm run build

✅ go

go — plain Go module, posthog-go already in the manifest, native debug symbols rather than source maps. The run wrote a Makefile that picks the linker flags per platform (-compressdwarf=false on darwin, -B gobuildid on linux, a hard error elsewhere) and follows the build with posthog-cli --dotenv-file .env symbol-sets upload --directory ./bin --include-source. Its run target carries -include .env plus export POSTHOG_PROJECT_TOKEN POSTHOG_HOST, so the binary actually receives the token.
Capture is a deferred recover() boundary at the process entry: it enqueues the panic with an explicit distinct id, closes the client to flush, then re-panics so Go keeps its normal crash behaviour.
runtime error: invalid memory address or nil pointer dereference — triggered by make run, resolved to main.kaboomGo2 -> main.readGoRetryBudget2 in main.go against symbols uploaded during the build.

symbol upload output (make build)
INFO posthog_cli::debug_symbols::upload: Processing bin/go-app
                                         (debug id 66C1B670-511A-3FE8-F6EE-552894F63132)
INFO posthog_cli::api::releases: Release wizard-e2e-go@e55468b727aadaafa56fbab93adddadcf455bade
                                 created successfully!
INFO posthog_cli::api::symbol_sets: Upload summary: 1 chunk(s) uploaded, 0 skipped
Stack trace
in_app  source   resolved_name
true    main.go  main.main
true    main.go  main.kaboomGo2
true    main.go  main.readGoRetryBudget2
true    main.go  main.main.func1   (the recover boundary)

✅ ios-spm

ios-spm — SwiftUI app on an Xcode project with posthog-ios already added through Swift Package Manager, so the run skipped install and init and went straight to capture plus dSYM upload. config.errorTrackingConfig.autoCapture = true went in immediately before the single PostHogSDK.shared.setup(config). On the target's Release configuration DEBUG_INFORMATION_FORMAT became dwarf-with-dsym, and a final Run Script phase calls the SDK's bundled uploader verbatim — POSTHOG_INCLUDE_SOURCE=1 POSTHOG_CLI_DOTENV_FILE="${SRCROOT}/.env" "${BUILD_DIR%/Build/*}/SourcePackages/checkouts/posthog-ios/build-tools/upload-symbols.sh" — with $(DWARF_DSYM_FOLDER_PATH)/$(DWARF_DSYM_FILE_NAME)/Contents/Resources/DWARF/$(EXECUTABLE_NAME) as its Input File. Credentials landed in a gitignored .env beside the .xcodeproj, POSTHOG_CLI_HOST set to the API host. No CI task ran — the repository carries no pipeline.
Built Release for the iOS 26.5 simulator, installed and launched it, and the exception came back with every frame resolved: retry budget is unreadable (Code: 42).

dSYM upload output (Release build phase)
INFO posthog_cli::dsym::upload: Found 1 dSYM bundle(s)
INFO posthog_cli::dsym::upload: Release name: com.example.SourceMapExampleSPM
INFO posthog_cli::dsym::upload: Release version: 2.0
INFO posthog_cli::dsym::upload: Build: 5
INFO posthog_cli::dsym: [lipo] thinned SourceMapExampleSPM (arm64 arch): 26862912 bytes → 13163168 bytes
INFO posthog_cli::dsym: Found 364 source paths in DWARF (364 after filtering)
INFO posthog_cli::dsym::source_bundle: Collected 361 source files (3838380 bytes total)
INFO posthog_cli::dsym::upload: Uploading 2 dSYM(s)...
INFO posthog_cli::api::symbol_sets: Upload summary: 2 chunk(s) uploaded, 0 skipped (0 already present, 0 too large)
INFO posthog_cli::dsym::upload: dSYM upload complete
** BUILD SUCCEEDED **
Stack trace
in_app  resolved_name                                              source
true    main                                                       SourceMapExampleSPMApp.swift
true    static SourceMapExampleSPMApp.$main                         SourceMapExampleSPMApp.swift
true    closure #1 in closure #1 in ContentView.body.getter
true    PostHogSDK.captureException
true    specialized static PostHogExceptionProcessor.buildExceptionList   PostHogExceptionProcessor.swift:196
true    specialized static PostHogExceptionProcessor.buildException       PostHogExceptionProcessor.swift:236
true    specialized static PostHogExceptionProcessor.buildStacktrace      PostHogExceptionProcessor.swift:373
true    static PostHogStackTraceProcessor.captureCurrentStackTraceWithMetadata  PostHogStackTraceProcessor.swift:27

✅ ios-pod

ios-pod — the same SwiftUI app on CocoaPods instead of SPM, PostHog 3.59.1 from the lockfile, so again the run skipped install and init and went to capture plus dSYM upload. config.errorTrackingConfig.autoCapture = true went in before PostHogSDK.shared.setup(config); DEBUG_INFORMATION_FORMAT became dwarf-with-dsym on both Release configurations, and a Run Script phase ordered after [CP] Embed Pods Frameworks calls the pod-bundled uploader — POSTHOG_INCLUDE_SOURCE=1 POSTHOG_CLI_DOTENV_FILE="${SRCROOT}/.env" "${PODS_ROOT}/PostHog/build-tools/upload-symbols.sh" — with $(DWARF_DSYM_FOLDER_PATH)/$(DWARF_DSYM_FILE_NAME)/Contents/Resources/DWARF/$(EXECUTABLE_NAME) as its Input File. It picked the CocoaPods path over the SPM one on its own. Credentials went to a .env the run added to .gitignore, POSTHOG_CLI_HOST set to the API host. No CI task ran — the repository carries no pipeline.
Built Release against the workspace for the iOS 26.5 simulator, installed and launched it, and the exception came back with every frame resolved: shipping quote is unavailable (Code: 77).

dSYM upload output (Release build phase)
INFO posthog_cli::dsym::upload: Found 2 dSYM bundle(s)
INFO posthog_cli::dsym::upload: Release name: com.example.SourceMapExamplePods
INFO posthog_cli::dsym::upload: Release version: 2.0
INFO posthog_cli::dsym::upload: Build: 5
INFO posthog_cli::api::releases: found release com.example.SourceMapExamplePods@2.0+5
INFO posthog_cli::dsym: Found 370 source paths in DWARF (370 after filtering)
INFO posthog_cli::dsym::source_bundle: Collected 370 source files (3913943 bytes total)
INFO posthog_cli::api::symbol_sets: Upload summary: 4 chunk(s) uploaded, 0 skipped (0 already present, 0 too large)
INFO posthog_cli::dsym::upload: dSYM upload complete
** BUILD SUCCEEDED **
Stack trace
in_app  resolved_name                                        source
true    main                                                 SourceMapExamplePodsApp.swift
true    static SourceMapExamplePodsApp.$main                  SourceMapExamplePodsApp.swift
true    closure #1 in closure #1 in ContentView.body.getter

✅ android

android — Gradle project with posthog-android already in the manifest, so the run skipped install and init. Android uploads R8 mapping files rather than source maps. errorTrackingConfig.autoCapture = true went onto the PostHogAndroidConfig in the Application class. In the app module's build.gradle.kts (never the root project) the run applied id("com.posthog.android") version "1.5.0" — the plugin is versioned separately from the SDK, and it did not reuse the SDK's 3.55.2 — flipped the release build type's isMinifyEnabled to true with its proguardFiles line untouched, since the plugin only hooks minified variants, and bridged the credentials in with a tasks.withType<PostHogCliExecTask>().configureEach { … } block reading a gitignored root .env. No CI task ran — the repository carries no pipeline.
./gradlew :app:assembleRelease ran uploadPostHogProguardMappingsRelease, then the APK went onto an API 36.1 emulator. R8 had renamed both helper functions to y; PostHog resolved them back from the uploaded mapping: android inventory count is unavailable.

mapping upload output (./gradlew :app:assembleRelease)
> Task :app:postHogGenerateMapIdTaskRelease
> Task :app:injectPostHogMetaPropertiesIntoAssetsrelease
> Task :app:minifyReleaseWithR8
> Task :app:uploadPostHogProguardMappingsRelease
INFO posthog_cli::api::releases: found release com.posthog.sourcemapexample@1.0+1
INFO posthog_cli::api::symbol_sets: Starting upload of batch 0, 1 symbol sets
INFO posthog_cli::api::symbol_sets: Server returned 1 upload keys (0 skipped as already present)
INFO posthog_cli::api::symbol_sets: Upload summary: 1 chunk(s) uploaded, 0 skipped (0 already present, 0 too large)

BUILD SUCCESSFUL in 26s
Stack trace
mangled  resolved_name              source
run      onCreate$lambda$4          MainActivity.kt:34
y        readInventoryCountAndroid  MainActivity.kt:40
y        kaboomAndroid              MainActivity.kt:45

(the framework frames below these — Looper, Handler, ZygoteInit — stay unresolved;
 platform code has no mapping to resolve against)

✅ no-posthog-express

no-posthog-express — Express server with no PostHog at all, so the run installed and initialised the SDK first. It added posthog-node plus dotenv, built the client with enableExceptionAutocapture: true behind a guard that throws outside production when the token is missing, and mounted setupExpressRequestContext before the routes and setupExpressErrorHandler after them. The build script gained posthog-cli --dotenv-file .env sourcemap process --directory ./dist --release-name no-posthog-express after esbuild, and .env carries the runtime pair (POSTHOG_PROJECT_TOKEN, POSTHOG_HOST) alongside the three POSTHOG_CLI_* upload variables.
The test error is an uncaught route error rather than a manual capture, so it travels the error-handler path: it arrives handled: false with mechanism.type: middleware, resolved to original source — Cannot read properties of undefined (reading 'expressRetryBudget').

Build output
dist/index.js      1.4kb
dist/index.js.map  2.4kb
INFO posthog_cli::api::releases: Release no-posthog-express@a65fe94 created successfully!
INFO posthog_cli::sourcemaps::source_pairs: found 1 pairs
INFO posthog_cli::sourcemaps::inject: injecting done
INFO posthog_cli::api::symbol_sets: Upload summary: 1 chunk(s) uploaded, 0 skipped (0 already present, 0 too large)
Stack trace
in_app  resolved_name             source
true    <anonymous>               ../index.js:46:2
true    kaboomExpress             ../index.js:42:9
true    readExpressRetryBudget    ../index.js:38:16

✅ no-posthog-fastify

no-posthog-fastify — Fastify server with no PostHog, so install and init ran first. The run added posthog-node and dotenv, built the client with enableExceptionAutocapture: true behind the missing-variable guard, and wired capture through Fastify's own hook — app.setErrorHandler((error, request, reply) => { posthog?.captureException(error); reply.send(error); }) — rather than a try/catch per route. The build script chains posthog-cli --dotenv-file .env sourcemap process --directory ./dist --release-name no-posthog-fastify after esbuild's ESM bundle, and .env.example documents all five variables: the runtime pair and the three POSTHOG_CLI_*.
An uncaught route error travels the setErrorHandler path and resolves to original source — Cannot read properties of undefined (reading 'fastifyRetryBudget').

Build output
dist/index.js      1.3kb
dist/index.js.map  2.1kb
INFO posthog_cli::api::releases: Release no-posthog-fastify@ec651e8 created successfully!
INFO posthog_cli::sourcemaps::source_pairs: found 1 pairs
INFO posthog_cli::api::symbol_sets: Upload summary: 1 chunk(s) uploaded, 0 skipped (0 already present, 0 too large)
Stack trace
in_app  resolved_name             source
true    <anonymous>               ../index.js:39:31
true    kaboomFastify             ../index.js:36:9
true    readFastifyRetryBudget    ../index.js:32:16

✅ no-posthog-hono

no-posthog-hono — Hono on @hono/node-server with no PostHog, so install and init ran first. The run added posthog-node and dotenv, built the client with enableExceptionAutocapture: true behind the missing-variable guard, and captured through Hono's own app.onError hook — passing a HTTPException's own response through when the error carries getResponse, and falling back to a 500 otherwise, so capture does not change the app's error semantics. The build script chains posthog-cli --dotenv-file .env sourcemap process --directory ./dist --release-name no-posthog-hono after esbuild's ESM bundle.
An uncaught route error travels the onError path and resolves to original source — Cannot read properties of undefined (reading 'honoRetryBudget').

Build output
dist/index.js      1.4kb
dist/index.js.map  2.5kb
INFO posthog_cli::api::releases: Release no-posthog-hono@286bb81 created successfully!
INFO posthog_cli::sourcemaps::source_pairs: found 1 pairs
INFO posthog_cli::api::symbol_sets: Upload summary: 1 chunk(s) uploaded, 0 skipped (0 already present, 0 too large)
Stack trace
in_app  resolved_name          source
true    <anonymous>            ../index.js:48:43
true    kaboomHono             ../index.js:45:9
true    readHonoRetryBudget    ../index.js:41:16

✅ no-posthog-koa

no-posthog-koa — Koa with no PostHog, so install and init ran first. The run added posthog-node and dotenv, built the client with enableExceptionAutocapture: true behind the missing-variable guard, and captured through Koa's own app.on('error', …) event rather than wrapping middleware. The build script chains posthog-cli --dotenv-file .env sourcemap process --directory dist --release-name no-posthog-koa after esbuild, and .env.example documents all five variables.
An uncaught route error reaches the app.on('error') listener and resolves to original source — Cannot read properties of undefined (reading 'koaRetryBudget').

Build output
dist/index.js      1.3kb
dist/index.js.map  2.3kb
INFO posthog_cli::api::releases: Release no-posthog-koa@581ca0b created successfully!
INFO posthog_cli::sourcemaps::source_pairs: found 1 pairs
INFO posthog_cli::api::symbol_sets: Upload summary: 1 chunk(s) uploaded, 0 skipped (0 already present, 0 too large)
Stack trace
in_app  resolved_name         source
true    <anonymous>           ../index.js:43:23
true    kaboomKoa             ../index.js:39:9
true    readKoaRetryBudget    ../index.js:35:16

✅ no-posthog-node-http

no-posthog-node-http — a bare node:http server with no PostHog and no framework, so there is no error hook to mount. The run added posthog-node and dotenv and leaned on enableExceptionAutocapture: true alone, which installs the SDK's process-level handler; it added no handler of its own, which is the right call here. The build script chains posthog-cli --dotenv-file .env sourcemap process --directory ./dist --release-name no-posthog-node-http --delete-after, so the .map is uploaded and then removed rather than shipped beside the bundle.
The test error is a real uncaught crash — the process dies and the connection drops — so the SDK has to capture and flush during teardown. It arrives handled: false with mechanism.type: onuncaughtexception, resolved to original source — Cannot read properties of undefined (reading 'nodeHttpRetryBudget').

Build output
dist/index.js.map  2.2kb
INFO posthog_cli::api::releases: Release no-posthog-node-http@754703d created successfully!
INFO posthog_cli::sourcemaps::source_pairs: found 1 pairs
INFO posthog_cli::api::symbol_sets: Upload summary: 1 chunk(s) uploaded, 0 skipped (0 already present, 0 too large)
INFO posthog_cli::sourcemaps::source_pairs: found 0 pairs   (--delete-after removed the map)
Stack trace
in_app  resolved_name              source
true    server                     ../index.js:35:4
true    kaboomNodeHttp             ../index.js:30:9
true    readNodeHttpRetryBudget    ../index.js:26:16

✅ no-posthog-javascript-web

no-posthog-javascript-web — vanilla browser JS on Vite with no PostHog, so install and init ran first. posthog.init sets capture_exceptions as an explicit object (capture_unhandled_errors and capture_unhandled_rejections on, capture_console_errors off), which in posthog-js takes precedence over the project's remote setting rather than deferring to it. Upload is the @posthog/rollup-plugin in vite.config.js with sourcemaps.enabled and deleteAfterUpload: true, reading POSTHOG_API_KEY / POSTHOG_PROJECT_ID / POSTHOG_HOST via loadEnv; the run added a version to package.json so releaseVersion resolves. The built dist/assets/ ships the .js with no .map beside it.
The test error is thrown from a click handler and left uncaught, so it reaches PostHog through window.onerrorhandled: false — with the minified Yh / Zh resolved back to real names: Cannot read properties of undefined (reading 'jsWebRetryBudget').

Build output
vite v6.4.3 building for production...
✓ 4 modules transformed.
INFO posthog_cli::api::releases: Release no-posthog-javascript-web@1.0.0 created successfully!
INFO posthog_cli::sourcemaps::source_pairs: found 1 pairs
INFO posthog_cli::api::symbol_sets: Upload summary: 1 chunk(s) uploaded, 0 skipped (0 already present, 0 too large)
dist/assets/index-2O-msM4v.js  305.78 kB │ gzip: 98.85 kB │ map: 1,027.05 kB
✓ built in 4.55s
Stack trace
mangled                        resolved_name           source
HTMLButtonElement.<anonymous>  <anonymous>             ../../src/main.js:42:2
Yh                             kaboomJsWeb             ../../src/main.js:37:9
Zh                             readJsWebRetryBudget    ../../src/main.js:33:16

✅ no-posthog-next

no-posthog-next — Next 16 app router with no PostHog, so install and init ran first. Init went into instrumentation-client.ts (capture_exceptions: true), and the run added app/global-error.tsx so React render errors are captured too — two paths, one init. Upload is withPostHogConfig in next.config.ts with sourcemaps.deleteAfterUpload, guarded by a ternary so a missing key falls back to the plain config instead of failing the type check. Credentials are split the way Next wants them: the public pair in .env.local, the build-time POSTHOG_API_KEY / POSTHOG_PROJECT_ID in .env.
The upload runs inside runAfterProductionCompile — 25 chunks uploaded, 7 already present. An uncaught click-handler error reaches PostHog through window.onerror (handled: false) and resolves to original source: Cannot read properties of undefined (reading 'nextRetryBudget').

Build output
✓ Compiled successfully in 738ms
INFO posthog_cli::api::releases: Release noph-next@eaa4076 created successfully!
INFO posthog_cli::sourcemaps::plain::upload: Found 38 chunks to upload
INFO posthog_cli::api::symbol_sets: Upload summary: 25 chunk(s) uploaded, 7 skipped (7 already present, 0 too large)
✓ Completed runAfterProductionCompile in 14.6s
✓ Generating static pages using 4 workers (3/3) in 143ms
Stack trace
mangled  resolved_name                source
onClick  <object>.children.onClick    turbopack:///[project]/app/page.tsx:7:16

✅ no-posthog-vue

no-posthog-vue — Vue 3 on Vite with no PostHog, so install and init ran first. Init is in src/main.js, and capture goes through Vue's own app.config.errorHandler rather than a global window hook, so component and handler errors are caught where Vue surfaces them. Upload is the @posthog/rollup-plugin in vite.config.js with sourcemaps.deleteAfterUpload, spread in conditionally so a project without upload credentials still builds.
The click handler throws and Vue routes it to errorHandler — the page never sees a window.onerror, which is how you can tell the wired path is the one that fired. Minified i / s / t all resolve back: Cannot read properties of undefined (reading 'vueRetryBudget').

Build output
INFO posthog_cli::api::releases: Release noph-vue@b069b62 created successfully!
INFO posthog_cli::api::symbol_sets: Upload summary: 1 chunk(s) uploaded, 0 skipped (0 already present, 0 too large)
dist/index.html                  0.31 kB │ gzip:   0.23 kB
dist/assets/index-BlRlAJp-.js  367.50 kB │ gzip: 122.94 kB │ map: 1,672.59 kB
✓ built in 4.65s
Stack trace
mangled  resolved_name           source
i        onKaboom                ../../src/App.vue:16:2
s        kaboomVue               ../../src/App.vue:11:9
t        readVueRetryBudget      ../../src/App.vue:7:16

✅ no-posthog-react-router

no-posthog-react-router — React Router 7 in framework mode (SSR) with no PostHog, so install and init ran first. Init went into app/entry.client.tsx ahead of hydrateRoot, with capture_exceptions as an explicit object. Upload is the @posthog/rollup-plugin in vite.config.ts alongside reactRouter(), with build.sourcemap: 'hidden' and deleteAfterUpload — and because framework mode runs two Vite passes, the plugin uploads twice: 5 client chunks, then 1 server chunk.
An uncaught click-handler error reaches PostHog through window.onerror (handled: false), with minified s / i resolved back through the hidden maps: Cannot read properties of undefined (reading 'rrRetryBudget').

Build output
INFO posthog_cli::api::releases: Release noph-rr@e6c4f51 created successfully!
INFO posthog_cli::sourcemaps::source_pairs: found 5 pairs
INFO posthog_cli::api::symbol_sets: Upload summary: 5 chunk(s) uploaded, 0 skipped (0 already present, 0 too large)
✓ built in 4.91s
INFO posthog_cli::sourcemaps::source_pairs: found 1 pairs
INFO posthog_cli::api::symbol_sets: Upload summary: 1 chunk(s) uploaded, 0 skipped (0 already present, 0 too large)
✓ built in 2.70s
Stack trace
mangled  resolved_name                source
onClick  <object>.children.onClick    ../../../app/routes/home.tsx:25:10
s        kaboomRr                     ../../../app/routes/home.tsx:9:9
i        readRrRetryBudget            ../../../app/routes/home.tsx:5:16

✅ no-posthog-sveltekit

no-posthog-sveltekit — SvelteKit 2 with no PostHog, so install and init ran first. The run wired both sides the way SvelteKit expects: src/hooks.client.ts does the browser init in init() (capture_exceptions: true) and captures via handleError, while src/hooks.server.ts captures server errors through a posthog-node client in src/lib/server/posthog.ts and awaits a flush before returning. Both handleError hooks return { message, status } unchanged, so capture does not alter what the user sees. Upload is the @posthog/rollup-plugin beside sveltekit(), spread in conditionally; it runs on both Vite passes — 14 client chunks then 15 server.
An uncaught click-handler error resolves to original source through the maps: Cannot read properties of undefined (reading 'svelteRetryBudget').

Build output
INFO posthog_cli::api::releases: Release noph-svelte@b6ef89d created successfully!
INFO posthog_cli::sourcemaps::source_pairs: found 14 pairs
INFO posthog_cli::api::symbol_sets: Upload summary: 14 chunk(s) uploaded, 0 skipped (0 already present, 0 too large)
✓ built in 4.11s
INFO posthog_cli::sourcemaps::source_pairs: found 15 pairs
INFO posthog_cli::api::symbol_sets: Upload summary: 15 chunk(s) uploaded, 0 skipped (0 already present, 0 too large)
✓ built in 9.77s
Stack trace
mangled              resolved_name              source
HTMLButtonElement.a  onKaboom                   src/routes/+page.svelte:19:4
s                    kaboomSvelte               src/routes/+page.svelte:14:11
t                    readSvelteRetryBudget      src/routes/+page.svelte:10:18

✅ no-posthog-angular

no-posthog-angular — Angular 21 standalone on the stock @angular/build builder, no PostHog. This is the platform with no environment to read from, and the run solved it the documented way: a prebuild/prestart script generates src/environments/environment.generated.ts from .env, so the committed source holds no token. Capture is Angular's own ErrorHandler, provided at bootstrap — it unwraps ngOriginalError, pulls the real error out of an HttpErrorResponse, and only then captures. Because that handler already sees every sync error, init deliberately sets capture_unhandled_errors: false while leaving rejections on, so nothing is captured twice. Upload chains posthog-cli sourcemap process --directory ./dist/browser after ng build --configuration production.
The click never reaches window.onerror — Angular intercepts it — and the trace resolves through the Angular runtime into app source: Cannot read properties of undefined (reading 'angularRetryBudget').

Build output
Initial chunk files | Names | Raw size  | Estimated transfer size
main.js             | main  | 398.95 kB |               112.17 kB
Application bundle generation complete. [1.079 seconds]
INFO posthog_cli::api::releases: Release no-posthog-angular@c81529f created successfully!
INFO posthog_cli::sourcemaps::source_pairs: found 1 pairs
INFO posthog_cli::api::symbol_sets: Upload summary: 1 chunk(s) uploaded, 0 skipped (0 already present, 0 too large)
Stack trace
mangled                    resolved_name                             source
HTMLButtonElement.<anon>   <anonymous>                               platform-browser/src/dom/dom_renderer.ts:465
r                          wrapListenerIn_markDirtyAndPreventDefault  core/src/render3/view/listeners.ts:67
Qd                         executeListenerWithErrorHandling           core/src/render3/view/listeners.ts:91
e.onKaboom                 App.onKaboom                               src/app/app.ts:37:9
e.kaboomAngular            App.kaboomAngular                          src/app/app.ts:32:16
e.readAngularRetryBudget   App.readAngularRetryBudget                 src/app/app.ts:28:18

✅ no-posthog-django

no-posthog-django — Django with no PostHog. Python stack traces are already readable, so the seed correctly skipped the whole upload subgraph: no credentials ask, no build config touched, no CLI dependency — the run went intro → auth → run → outro with no interruption at all. It installed posthog and python-dotenv, added load_dotenv and the POSTHOG_PROJECT_TOKEN / POSTHOG_HOST settings, registered posthog.integrations.django.PosthogContextMiddleware, and built the client in an AppConfig.ready() with enable_exception_autocapture=True, publishing it as settings.POSTHOG_MW_CLIENT (the name the middleware reads) and registering atexit shutdown so buffered events flush on exit.
An uncaught view error resolves straight to source, no symbolication involved: 'NoneType' object is not subscriptable.

run output (no build step — upload subgraph skipped)
screen path: error-tracking-intro → health-check → auth → run → outro
new deps   : (none in package.json — Python project)
requirements.txt: Django>=4.2,<5.0 / posthog==6.9.3 / python-dotenv>=1.0.0

GET /       -> {"service": "django", "status": "ok"}
GET /kaboom -> 500
Stack trace
in_app  resolved_name                source
true    kaboom_django                config/urls.py:15
true    read_django_retry_budget     config/urls.py:11

✅ no-posthog-nuxt

no-posthog-nuxt — Nuxt 4.3 with no PostHog, so install and init ran first. Init is app/plugins/posthog.client.ts, reading runtimeConfig.public.posthog and capturing through Nuxt's own vue:error hook. Upload is the CLI recipe from the Nuxt reference, copied verbatim into the nitro:build:public-assets hook — posthog-cli sourcemap inject then sourcemap upload --delete-after over .output — with sourcemap.client on and nitro.rollupConfig.output.sourcemapExcludeSources: false so the uploaded maps carry their sources.
The hook choice is the load-bearing detail: nitro:build:public-assets fires before Nitro writes the asset manifest that records each file's size, so the injected chunk ids are accounted for. Served bytes match disk exactly (Content-Length: 432520), the page loads clean, and the trace resolves: Cannot read properties of undefined (reading 'nuxtRetryBudget').

Build output
Running PostHog sourcemap injection and upload...
INFO posthog_cli::sourcemaps::source_pairs: found 4 pairs
INFO posthog_cli::api::releases: Release noph-nuxt2@7c1399a created successfully!
INFO posthog_cli::api::symbol_sets: Upload summary: 4 chunk(s) uploaded, 0 skipped (0 already present, 0 too large)
PostHog sourcemap injection completed successfully

$ wc -c .output/public/_nuxt/-ClrXyTd.js     ->  432520
$ curl -sD- localhost:3000/_nuxt/-ClrXyTd.js ->  Content-Length: 432520   (served == disk)
Stack trace
mangled  resolved_name           source
i        onKaboom                ../../../app/app.vue:18:2
s        kaboomNuxt              ../../../app/app.vue:13:9
t        readNuxtRetryBudget     ../../../app/app.vue:9:16

LLM context

Built with Claude Code. The flow follows replay-vision (wizard) and error-tracking-upload-source-maps (context-mill).

🤖 Generated with Claude Code

https://claude.ai/code/session_01668rN31F4aotxmenNksz4Z

…tor flow

New `wizard error-tracking` command. Modeled on replay-vision: a detect
step carries the framework id into orchestrator preflight, the
context-mill `error-tracking` flow seeds install/init (integration-v2
step-skills) when the repo has no PostHog, then exception capture, then
the source-map subgraph where the platform needs it. The detect step
also pre-installs posthog-cli for symbol-upload platforms, which the
agent cannot (warlock blocks npm install -g).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PVXmLWB31CBujD2FJ2ogvY
@github-actions

github-actions Bot commented Sep 1, 2026

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 ai-observability
  • /wizard-ci basic-integration
  • /wizard-ci mcp-analytics
  • /wizard-ci replay-vision
  • /wizard-ci revenue
  • /wizard-ci self-driving
  • /wizard-ci warehouse
  • /wizard-ci warehouse-seeded

Test an individual app:

  • /wizard-ci ai-observability/anthropic
  • /wizard-ci ai-observability/groq
  • /wizard-ci ai-observability/manual-capture
Show more apps
  • /wizard-ci ai-observability/openai
  • /wizard-ci ai-observability/openai-agents
  • /wizard-ci ai-observability/vercel-ai
  • /wizard-ci basic-integration/android
  • /wizard-ci basic-integration/angular
  • /wizard-ci basic-integration/astro
  • /wizard-ci basic-integration/django
  • /wizard-ci basic-integration/fastapi
  • /wizard-ci basic-integration/flask
  • /wizard-ci basic-integration/flutter
  • /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 replay-vision/javascript-node
  • /wizard-ci replay-vision/next-js
  • /wizard-ci replay-vision/react-vite
  • /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
  • /wizard-ci warehouse/monorepo-env
  • /wizard-ci warehouse/multi-source-next
  • /wizard-ci warehouse/stripe-node
  • /wizard-ci warehouse/zero-source
  • /wizard-ci warehouse-seeded/next-stripe
  • /wizard-ci warehouse-seeded/next-stripe-declined

Test against a Context Mill branch:

  • /wizard-ci all context-mill:my-branch

Add context-mill:<branch> to any command above to pin the Context Mill branch. It defaults to main.

Results will be posted here when complete.

ablaszkiewicz and others added 5 commits September 1, 2026 18:21
Binding harness anthropic→pi, like metrics: the binding routes only,
and every stage's model and effort are pinned context-mill side in the
flow's frontmatter (terra seed, sol tasks, luna report).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PVXmLWB31CBujD2FJ2ogvY
e2e.json flow definition + profile registration: the driver confirms
the intro, answers the flow's api-key ask from SOURCE_MAPS_CLI_KEY
(secret rule, vaulted by the ask tool) and declines the test-affordance
offer. Two variations: the pinned orchestrator-on-pi binding and the
linear fallback. Unlocks snapshots mode and the workbench e2e runner
for the command.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PVXmLWB31CBujD2FJ2ogvY
The screen was registered in the action registry (satisfying the
exhaustiveness test) but decideE2eAction keeps its own intro switch,
and an unlisted screen falls through to wait — the driver sat on the
intro until the host died. Adds the missing case.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PVXmLWB31CBujD2FJ2ogvY
The bin resolves --local-* flags in its yargs middleware into the
local-dev singleton that getSkillsBaseUrl() reads. The tui-host
bypasses yargs, so its env-backed local flags reached the session but
never the singleton — agent prompts always resolved to production, and
an unpublished flow died in preflight with "No seed agent prompt".
Initialize the singleton from the same env spellings before the store
starts.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PVXmLWB31CBujD2FJ2ogvY
The MCP facade runs ensureGitignoreCoverage after every write; the pi
facade, which is the arm the orchestrator flows run on, did not. Projects
whose .gitignore already lists .env hid it — an Xcode project's lists
xcuserdata/ and nothing else, so the personal API key the error-tracking
flow writes was left staged for the next `git add`.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01X5Kw3YahYz9RiFeJ8r2hxY
@gewenyu99

Copy link
Copy Markdown
Collaborator

Let's fucking gooooooooo

ablaszkiewicz and others added 4 commits September 14, 2026 11:33
Resolve conflicts in scripts/tui-host.no-jest.ts (keep initLocalDev and the
gateway setup) and switchboard.test.ts (error-tracking follows main's metrics
case). Update the binding comment and the e2e summary for terra install/init.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013SEsZQQrYjXPVEhQuoSwE6
…install

- The interactive detect step now aborts with DetectNoFramework when
  detection finds nothing, like ciPreRun. Before, bootstrap put the program
  id on session.skillId and preflight failed with a misleading
  "failed to download" message.
- error-tracking and error-tracking-upload-source-maps now call one
  once-per-process helper, preinstallPostHogCliOnce. A failed install is an
  event and a warning, no longer a captureException per machine.
- The test derives the error-tracking CLI set from
  VARIANTS_REQUIRING_POSTHOG_CLI instead of a hardcoded list.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013SEsZQQrYjXPVEhQuoSwE6
…skill

After detect, session.skillId holds the framework, so the lookup found the
wrong skill or none. Use integration-v2-error-tracking-step, the skill every
run of the flow installs, and drop the argument useSkillEntry does not take.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013SEsZQQrYjXPVEhQuoSwE6
set_env_values refused POSTHOG_KEY on every call. In a project whose code
already reads that name, the agent had to rename working code, and every
deploy step and CI secret that still passed POSTHOG_KEY then started the app
with an empty token.

Both facades now share legacyKeyNameRefusal. It still refuses the name in a
project that does not read it, so new projects keep the canonical names.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013SEsZQQrYjXPVEhQuoSwE6
@posthog

posthog Bot commented Sep 14, 2026

Copy link
Copy Markdown
Contributor

🦔 PostHog Review reviewed this pull request

Found 2 must fix, 6 should fix, 2 consider.

Published 10 findings (view the review).

The flow no longer turns on Error Tracking on the backend. It relies on SDK
autocapture only. Remove error_tracking:read and product_enablement:write
from the program's scopes, and add a test that keeps product_enablement:write
out.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01668rN31F4aotxmenNksz4Z
@posthog

posthog Bot commented Sep 14, 2026

Copy link
Copy Markdown
Contributor

PostHog Review alpha 🦔 If you find any issues helpful - please reply "valid", "invalid", etc., for evaluation purposes 🙏

@posthog posthog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PostHog Review

Found 2 must fix, 6 should fix, 2 consider.

Comment thread src/lib/programs/error-tracking/index.ts
Comment thread src/ui/tui/screens/ErrorTrackingIntroScreen.tsx
Comment thread src/lib/programs/shared/posthog-cli-preinstall.ts
Comment thread src/lib/oauth/program-scopes.ts Outdated
Comment thread src/lib/programs/error-tracking/index.ts Outdated
Comment thread src/lib/programs/error-tracking/index.ts Outdated
Comment thread src/lib/wizard-tools/tools.ts Outdated
Comment thread src/lib/programs/error-tracking/index.ts Outdated
Comment thread src/lib/programs/error-tracking/index.ts
Comment thread src/lib/programs/error-tracking/index.ts
ablaszkiewicz and others added 3 commits September 14, 2026 17:06
The detect step ran `npm install -g @posthog/cli` before the intro screen, so
Cancel left a global install behind. `run` is now a function, and `runAgent`
resolves it after the intro gate and after `ciPreRun`.

KMP skill variants have no `framework` tag, so preflight aborted every KMP run.
The detect step and `ciPreRun` now stop KMP with an unsupported-platform exit.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01668rN31F4aotxmenNksz4Z
The menu expands a bundle into per-framework entries, so no entry keeps the
bundle id. Match the group when the other rules find nothing.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01668rN31F4aotxmenNksz4Z
Add shell scripts, Gradle and Xcode config, Makefile, Procfile and the
package/app/eas JSON files to the scan that keeps a POSTHOG_KEY name.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01668rN31F4aotxmenNksz4Z
@ablaszkiewicz
ablaszkiewicz marked this pull request as ready for review September 14, 2026 15:23
Copilot AI lite review requested due to automatic review settings September 14, 2026 15:23
@ablaszkiewicz
ablaszkiewicz requested review from a team as code owners September 14, 2026 15:23

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

…k and tips

The program detected one framework in the install dir before the intro, so a
monorepo root got no choice. A post-login screen now scans the repo and lets
the user pick the project, as the legacy upload-source-maps program did. The
run step's targetDir scopes the orchestrator run to that project, and
run-wizard (and the e2e host) walk the steps when a step sets targetDir.

The run screen plays the source-maps learn deck, worded for platforms that
upload nothing, then error-tracking tips instead of the generic ones.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01668rN31F4aotxmenNksz4Z
@gewenyu99

Copy link
Copy Markdown
Collaborator

Agent DAG for the error-tracking flow

context-mill agent DAGs — error-tracking flow

Generated with the repo's built-in visualizer on the PR branch:

git fetch origin pull/393/head && git checkout FETCH_HEAD
npm run visual-dags

Console output for error-tracking:

error-tracking: 9 agents in 6 waves — 3 → 1 → 1 → 1 → 1 → 1

The diagram is the full page for context (also shows integration-v2, metrics, replay-vision); the new error-tracking flow is the first section.


Created with PostHog Desktop

@gewenyu99 gewenyu99 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ohhh man this is much cleaner than I thought. I also have comments for you to confirm, but tentative stamp/ Running rn

Comment thread src/ui/tui/screens/ErrorTrackingIntroScreen.tsx Outdated
Comment thread src/ui/tui/screens/ErrorTrackingIntroScreen.tsx Outdated
Comment thread src/lib/wizard-tools/tools.ts
Comment thread src/lib/programs/shared/posthog-cli-preinstall.ts
Comment thread src/lib/programs/shared/posthog-cli-preinstall.ts
Comment thread src/lib/programs/error-tracking/detect-agentic.ts
ablaszkiewicz and others added 3 commits September 15, 2026 16:48
Co-authored-by: Vincent (Wen Yu) Ge <29069505+gewenyu99@users.noreply.github.com>
Co-authored-by: Vincent (Wen Yu) Ge <29069505+gewenyu99@users.noreply.github.com>
Review feedback: error-tracking's detect adapter copied self-driving's match
of each scanned project to an Integration. toIntegrationCandidates in
project-scope now does it once. Each program keeps its own classification,
and the error-tracking adapter documents how its rule differs.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01668rN31F4aotxmenNksz4Z
@ablaszkiewicz
ablaszkiewicz requested a review from a team as a code owner September 15, 2026 15:04
@ablaszkiewicz
ablaszkiewicz merged commit 632b80a into main Sep 15, 2026
18 checks passed
@ablaszkiewicz
ablaszkiewicz deleted the error-tracking-program branch September 15, 2026 15:34
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.

3 participants