Skip to content

fix(env-upload): surface Vercel env var upload failures instead of skipping silently - #936

Draft
MattBro wants to merge 2 commits into
mainfrom
matt/env-upload-loud-failures
Draft

fix(env-upload): surface Vercel env var upload failures instead of skipping silently#936
MattBro wants to merge 2 commits into
mainfrom
matt/env-upload-loud-failures

Conversation

@MattBro

@MattBro MattBro commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

Problem

When the wizard finishes an install it tries to upload the env vars to the user's hosting provider (Vercel is the only provider today). That upload is skipped far more often than it succeeds — over the last 30 days: 5,504 wizard: env upload skipped events vs 414 wizard: env uploaded, and the skip event carries a single generic reason ("no environment provider found") with no detail on why.

The skip is also silent for the user. If they deploy to Vercel without copying the vars themselves, the deployed site sends no events, and nothing during the wizard run warned them. This is a recurring theme in wizard feedback: analytics that work locally and are silently dead in production.

Changes

  • The env upload step now returns a structured skip (EnvUploadSkip) when a project looks like it deploys to a provider but the upload can't run, with a typed cause: cli-missing, project-unlinked, or unauthenticated.
  • Each provider can implement describeSkip(); the Vercel provider detects Vercel markers (vercel.json, .vercel/, etc.) and reports which precondition failed.
  • When a skip happens the wizard prints a loud warning telling the user the vars were NOT added to their hosting provider and their deployed site won't send events until they add them.
  • The outro screen repeats the warning next to the env var list.
  • Telemetry: the skip event now carries deploy_target and skip_cause properties so the skip population becomes attributable, and successful uploads report variable_count/variable_keys.
  • A detected provider whose uploads all fail is now also a loud skip (skip_cause: upload-failed) instead of a silent return, and env uploaded no longer fires when nothing was uploaded.
  • The replace-existing-var path (rm then re-add, since Vercel has no upsert) retries the re-add once; if it still fails the error states plainly that the variable was removed and must be re-created.

Test plan

  • 1,549 tests pass locally (pnpm test), including new tests for skip detection, the upload-failed path, the rm-then-readd failure path, and the outro warning wiring.
  • pnpm run lint — no errors.

…ipping silently

The wizard wrote env vars to local .env files and, when no environment
provider passed detect(), returned silently. A project that deploys to
Vercel but has no usable CLI got no PostHog events in production and no
indication anything was missing.

Detect Vercel deploy markers (vercel.json, .vercel/) independently of CLI
availability, so a skip on a Vercel-marked repo prints the failing cause
(CLI missing / project unlinked / not authenticated), the env var key
names, and the vercel env add commands to run. Values stay out of the
output. The outro's change list gains a matching follow-up line, and the
skip event carries deploy_target/skip_cause alongside a new
vercel-markers-found tag so the deployer share is measurable.

Also upsert on conflict: uploadEnvironmentVariable now removes and re-adds
a variable Vercel reports as already existing, rather than failing the
upload and telling the user to do it by hand.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@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.

Review fixes: the remove-then-readd upsert path now retries once and
names the data loss plainly if the re-add still fails; a detected
provider whose uploads all fail now produces the same loud skip and
telemetry as a missing provider instead of returning silently; the
outro warning wiring is extracted into a tested helper pair.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LV8ErU3QavwTp2oMe9VSLS
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