Skip to content

fix(cli): stop reporting backend upload failures as bad API keys - #2955

Draft
posthog-eu[bot] wants to merge 1 commit into
mainfrom
posthog-self-driving/fixcli-stop-treating-backend-70bd25
Draft

fix(cli): stop reporting backend upload failures as bad API keys#2955
posthog-eu[bot] wants to merge 1 commit into
mainfrom
posthog-self-driving/fixcli-stop-treating-backend-70bd25

Conversation

@posthog-eu

@posthog-eu posthog-eu Bot commented Aug 9, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Who is hurt: users running capgo bundle upload are told their API key is bad when the backend hiccups, and every failure opens a new error-tracking issue. The exception fired 126 times across 47 fingerprints from 16 installs in 30 days, still firing on 2026-08-09.
  • Root cause: getUserIdFromApikey returned null for any Postgres failure, not just a missing user. The files service then returned 400 user_not_found, so a transient database blip reached the user as a bad key. On the CLI, the flattened error carried no status and user_not_found was not an expected-error marker, so it was reported as a crash.
  • Some failures are not user errors: on 2026-08-06 a single caller hit six failures in two seconds, each with a well-formed 36-character key — a backend blip, not six bad keys.

Changes

Layer Before After
getUserIdFromApikey swallows a query failure, returns null rethrows the failure, so a blip surfaces as 500
checkWriteAppAccess 400 user_not_found 401 user_not_found, matching invalid_apikey on the same route
CLI uploadTUS / delta partial.ts delta path rejects the raw tus blob (leaks URL + per-file object key, no status) both build a real Error via a shared buildTusUploadError helper carrying status, backend message, and request id
isExpectedUserError misses user_not_found matches it by the attached .status (401) and by a new marker

A genuine missing user now returns 401 and the CLI treats it as an auth error (no error-tracking issue). A transient database fault now returns 500, so users are no longer told to rotate a valid key.

Merging this fix also cuts a CLI release that carries the earlier merged fixes (#2885, #2933, #2934, #2947) that no released build contains yet.

Test plan

  • cd cli && bun run typecheck && bun run lint && bun test/test-posthog-exception.mjs — all pass.
  • Added cases to test-posthog-exception.mjs: a bare user_not_found Error and a tus error carrying .status = 401 are both classified as expected user errors.
  • oxlint clean on the changed backend files.

Screenshots

Not applicable — CLI error-classification and backend status-code change, no visual surface.

Checklist

  • My code follows the code style of this project and passes
    bun run lint:backend && bun run lint.
  • My change requires a change to the documentation.
  • I have updated the documentation
    accordingly.
  • My change has adequate E2E test coverage.
  • I have tested my code manually, and I have provided steps how to reproduce
    my tests

Agent context

  • The native build upload path (cli/src/build/request.ts) has a third copy of the tus-error shaping. It belongs to a different command than this symptom, so it was left untouched to keep the change scoped.

Created with PostHog Desktop from this inbox report.


View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need. Autofix is disabled.

Review in cubic

A transient database failure in `getUserIdFromApikey` returned null, which the
files service reported as `400 user_not_found`. The CLI showed users a bad-key
message and opened an error-tracking issue for each failure.

Backend:
- `getUserIdFromApikey` now rethrows a query failure instead of returning null,
  so a backend blip surfaces as a 500, not a missing user.
- `checkWriteAppAccess` returns `401 user_not_found` (was 400), matching how
  `invalid_apikey` behaves on the same route.

CLI:
- Add a shared `buildTusUploadError` helper that turns a tus failure into a real
  Error carrying the HTTP status, backend message, and request id. `uploadTUS`
  and the delta path (`partial.ts`) both use it, so the delta path no longer
  rejects the raw tus blob that leaked the URL and per-file object key.
- The attached `.status` and the new `user_not_found` marker let
  `isExpectedUserError` classify the auth failure and skip error tracking.

Merging this fix cuts a CLI release that also carries the earlier fixes (#2885,
#2933, #2934, #2947) that no released build contains yet.

Generated-By: PostHog Code
Task-Id: c66eba6b-af49-4627-84ac-2c007ed83bc0
@codspeed-hq

codspeed-hq Bot commented Aug 9, 2026

Copy link
Copy Markdown
Contributor

Merging this PR will not alter performance

✅ 43 untouched benchmarks
⏩ 2 skipped benchmarks1


Comparing posthog-self-driving/fixcli-stop-treating-backend-70bd25 (2153819) with main (b62668a)

Open in CodSpeed

Footnotes

  1. 2 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports.

@sonarqubecloud

sonarqubecloud Bot commented Aug 9, 2026

Copy link
Copy Markdown

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