Skip to content

fix: treat blank optional env strings as undefined in API config - #160

Open
apatt124 wants to merge 1 commit into
theam:mainfrom
apatt124:fix/config-optional-string-empty-env-values
Open

fix: treat blank optional env strings as undefined in API config#160
apatt124 wants to merge 1 commit into
theam:mainfrom
apatt124:fix/config-optional-string-empty-env-values

Conversation

@apatt124

Copy link
Copy Markdown

What

Seven fields in EnvSchema used z.string().trim().min(1).optional() without a preprocess step to coerce empty strings to undefined. When dotenv loads a blank value (e.g. VERCEL_TOKEN=) it produces "", not undefined, so Zod's .optional() never applies and .min(1) fails with a validation error at startup.

Affected fields:

  • VERCEL_TOKEN
  • VERCEL_OIDC_TOKEN
  • VERCEL_TEAM_ID
  • VERCEL_PROJECT_ID
  • FACILITY_AWS_CODEBUILD_PROJECT
  • FACILITY_AWS_CODEBUILD_CACHE_BASE_LOCATION
  • PACKAGE_REGISTRY_TOKEN

How

The fix follows the pattern already established in the codebase for OptionalUrl, OptionalGithubOrganization, and FACILITY_PREVIEW_SURFACE_TOKEN: a preprocess step that converts blank strings to undefined before Zod's type checking runs. This change extracts that pattern into an OptionalString helper and applies it to the affected fields.

How I found it

Hit this following the quickstart in the README. Running pnpm dev with a fresh .env (generated from .env.example) crashes the API and worker immediately on startup because .env.example leaves these fields blank. The stack never comes up without either filling in Vercel/CodeBuild credentials you don't have, or manually deleting the blank lines.

Also adds *.pem to .gitignore — the quickstart guide instructs users to generate a GitHub App private key which downloads as a .pem file, and the repo root is the natural place to put it.

Verification

Confirmed locally: fresh .env from .env.example with all optional fields blank, API and worker both start cleanly after this fix.

Seven fields in the API EnvSchema used z.string().trim().min(1).optional()
without a preprocess step to coerce empty strings to undefined. When dotenv
loads a blank value (e.g. VERCEL_TOKEN=) it produces an empty string, not
undefined, so Zod's .optional() never applies and .min(1) fails.

The same pattern was already solved correctly in the codebase for other
optional fields (OptionalUrl, OptionalGithubOrganization, and
FACILITY_PREVIEW_SURFACE_TOKEN all use a preprocess that converts blank
strings to undefined). This change introduces an OptionalString helper
that applies the same treatment and uses it for the affected fields:

- VERCEL_TOKEN
- VERCEL_OIDC_TOKEN
- VERCEL_TEAM_ID
- VERCEL_PROJECT_ID
- FACILITY_AWS_CODEBUILD_PROJECT
- FACILITY_AWS_CODEBUILD_CACHE_BASE_LOCATION
- PACKAGE_REGISTRY_TOKEN

Also adds *.pem to .gitignore. The quickstart guide instructs users to
generate a GitHub App private key which downloads as a .pem file — a
natural place to put it is the repo root, and it should be ignored by
default to prevent accidental commits.
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