fix(api): treat empty OPENAI_API_KEY/BASE_URL as unset (#4083) - #4438
Open
SomSamantray wants to merge 4 commits into
Open
fix(api): treat empty OPENAI_API_KEY/BASE_URL as unset (#4083)#4438SomSamantray wants to merge 4 commits into
SomSamantray wants to merge 4 commits into
Conversation
Docker Compose passes unset .env vars through as empty strings. The config schema kept them, so createOpenAI received apiKey:"" and baseURL:"", producing "Failed to parse URL from /responses" and a silent json-format failure that still billed credits. Apply the existing emptyStringAsUndefined helper (now also trimming whitespace-only values) to OPENAI_API_KEY and OPENAI_BASE_URL so the intended missing-key error and default base URL apply. Adds a regression test covering empty, whitespace-only, real, and unset values.
…wl#4083) Review found the config-layer coercion alone was a no-op: @ai-sdk/openai re-reads process.env at request time via loadApiKey/loadOptionalSetting when the createOpenAI option is undefined, so docker-compose's '' was resurrected and the 'Failed to parse URL from /responses' failure persisted. - Delete OPENAI_API_KEY/OPENAI_BASE_URL from process.env after parse when coerced to undefined, so the SDK env fallback sees unset and the intended missing-key error / default base URL apply. Warn at boot when a set-but-empty key is dropped (console.warn: importing the winston logger here would create a config <-> logger cycle). - Keep emptyStringAsUndefined at exact-'' semantics and add emptyOrWhitespaceStringAsUndefined for the fields that need it (OPENAI_*, FIREBRAIN_TRACKS_*), so whitespace-only FIREBILL_URL and secrets still fail closed at boot instead of silently disabling billing. - Move the regression test into src/__tests__/snips/v2/ so CI's 'pnpm harness pnpm test:snips' lane actually executes it, and assert process.env deletion, FIREBRAIN behavior, and padded passthrough.
Contributor
There was a problem hiding this comment.
All reported issues were addressed across 2 files
Reply with feedback, questions, or to request a fix.
Fix all with cubic | Re-trigger cubic
- Trim OPENAI_API_KEY/OPENAI_BASE_URL values so whitespace-padded keys and URLs are normalized before reaching createOpenAI (a padded key would otherwise auth with trailing spaces and 401 with no warning). - Differentiate boot warnings: an empty API key makes the OpenAI provider unavailable; an empty base URL merely falls back to the default https://api.openai.com/v1 (the provider still works when a key is present). - Restore FIREBRAIN_TRACKS_URL/API_KEY in the config test afterAll so the env-mutation test does not leak into other tests.
Author
|
All 3 review findings addressed in 0fdb590:
Verified: 8/8 config tests pass (incl. trimmed-padded assertions), 45 tests total, typecheck clean for changed files. |
Author
CI statusAll code-side checks are green and all review feedback is resolved. The PR is blocked only on maintainer-side approvals that an external contributor cannot perform:
Resolved this round:
Once a maintainer approves the workflow runs, the real test suite will execute against |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Self-hosted deployments that pass
OPENAI_API_KEY/OPENAI_BASE_URLthrough docker-compose${VAR}passthrough receive empty strings when the variables are unset in.env. The config schema accepted"", socreateOpenAIreceived a literal emptyapiKey/baseURL, andformats: ["json"]requests failed withFailed to parse URL from /responses— returningsuccess: truewith nojsonfield while still billing credits.Fixes #4083.
What changed
emptyStringAsUndefinedkeeps its exact-""semantics. A newemptyOrWhitespaceStringAsUndefinedhelper also coerces whitespace-only strings, and is used only where a whitespace-only value is never meaningful:OPENAI_API_KEY,OPENAI_BASE_URL, and theFIREBRAIN_TRACKS_*pair (which already had inline trim behavior).FIREBILL_URL,FIREBILL_SECRET,KEYLESS_CONVERSION_HMAC_SECRET,MCP_DELEGATED_CREDENTIAL_SECRET, etc.) are untouched — a whitespace-onlyFIREBILL_URLstill fails validation at startup instead of silently disabling billing routing.@ai-sdk/openaire-readsprocess.envat request time vialoadApiKey/loadOptionalSettingwhen thecreateOpenAIoption isundefined. Soconfig.tsnow deletesOPENAI_API_KEY/OPENAI_BASE_URLfromprocess.envafter parsing when they were coerced toundefined, and warns at boot. The SDK then raises the intended missing-key error and falls back to the default base URL.src/__tests__/snips/v2/so CI'spnpm harness pnpm test:snipslane executes it, and now also assertsprocess.envdeletion, FIREBRAIN behavior, and whitespace-padded passthrough.Verification
vitest run src/__tests__/snips/v2/config.test.ts— 8/8 pass (empty, whitespace-only, real, unset,process.envdeletion, FIREBRAIN, padded passthrough).@ai-sdk/openai3.0.71: before, env""produced request URL"/responses"(theERR_INVALID_URLfailure); after, the resolved URL uses the defaulthttps://api.openai.com/v1base.vitest run src/search/highlights.test.ts src/lib/threat-protection/config.test.ts— pass (45 tests total).tsc --noEmit— no errors in changed files (remaining repo-wide errors are pre-existing@mendable/firecrawl-rsnative-module resolution, built by CI).Impact
emptyStringAsUndefinedusers is unchanged (exact-""semantics preserved).Summary by cubic
Fixes self-hosted deployments where docker-compose
${VAR}passthrough exposes emptyOPENAI_API_KEYandOPENAI_BASE_URLstrings. Empty and whitespace-only values are now treated as unset, so@ai-sdk/openairaises the intended missing-key error and falls back to the default base URL instead of failing per-request and still billing credits.Bug Fixes
emptyOrWhitespaceStringAsUndefinedforOPENAI_*andFIREBRAIN_TRACKS_*vars; real values are trimmed so padded keys and URLs reach the SDK normalized.process.envafter config parse, since the SDK re-reads env at request time. Boot warnings differentiate: an empty key makes the OpenAI provider unavailable, while an empty base URL falls back to the default.FIREBILL_*,KEYLESS_*,MCP_DELEGATED_*) keep exact-""semantics, so whitespace-only values still fail validation at startup.src/__tests__/snips/v2/so CI's snips lane runs them; coverage includes empty, whitespace-only, real, unset, trimming, andprocess.envdeletion cases.Written for commit 0fdb590. Summary will update on new commits.