fix: keep NVIDIA NIM availability validation fail-open - #13
Merged
jyje merged 1 commit intoAug 14, 2026
Merged
Conversation
`unavailable` aborts the run before inference with no override, so every inconclusive catalogue lookup that resolves to it is a total blocker. Four paths could reach it without evidence that the model cannot be invoked. - Derive "custom endpoint" by comparing the resolved base URL against the provider's built-in default rather than testing whether the env var is set. Pinning `NVIDIA_BASE_URL` to the documented hosted endpoint made the public hosted catalogue authoritative over entitlement it does not model. - Treat an empty `data` array as `unknown`. A proxied gateway that hides its catalogue from a key without list scope still serves inference. - Bound the lookup with a 5s `AbortSignal.timeout`. The request now targets user-supplied infrastructure, where a stalled host held every run for undici's 300s default. - Build the catalogue URL from `pathname` so a base URL carrying a query string keeps its last path segment, and fall back to `unknown` if the URL cannot be resolved at all. Also surface the availability reason in the thrown error, which previously blamed credentials for a model simply not loaded on the endpoint. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
jyje
merged commit Aug 14, 2026
340fbd8
into
feat/nvidia-model-availability-validation
8 checks passed
jyje
added a commit
that referenced
this pull request
Aug 29, 2026
`unavailable` aborts the run before inference with no override, so every inconclusive catalogue lookup that resolves to it is a total blocker. Four paths could reach it without evidence that the model cannot be invoked. - Derive "custom endpoint" by comparing the resolved base URL against the provider's built-in default rather than testing whether the env var is set. Pinning `NVIDIA_BASE_URL` to the documented hosted endpoint made the public hosted catalogue authoritative over entitlement it does not model. - Treat an empty `data` array as `unknown`. A proxied gateway that hides its catalogue from a key without list scope still serves inference. - Bound the lookup with a 5s `AbortSignal.timeout`. The request now targets user-supplied infrastructure, where a stalled host held every run for undici's 300s default. - Build the catalogue URL from `pathname` so a base URL carrying a query string keeps its last path segment, and fall back to `unknown` if the URL cannot be resolved at all. Also surface the availability reason in the thrown error, which previously blamed credentials for a model simply not loaded on the endpoint. Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
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
Follow-up review fixes for
feat/nvidia-model-availability-validation(upstream PR langchain-ai#492). Targets that branch, notmain.unavailableis a hard stop.resolveRunConfigthrows, the error is taggedconfig, and the run aborts before inference with no bypass env var. That makes every inconclusive catalogue lookup that resolves tounavailablea total blocker, which is the opposite of what the feature intends. Four paths could reach it without any evidence that the model cannot be invoked.What changed
Custom endpoint detection compares URLs, not env presence.
baseUrlIsCustomwas derived fromNVIDIA_BASE_URLmerely being set. The provider's built-in default is alreadyhttps://integrate.api.nvidia.com/v1, so a user who pins that exact value (from a shared.envtemplate, a compose file, or just being explicit after reading the README's "alternative base URLs" note) flipped the flag totrueand made the hosted catalogue authoritative. That catalogue is a public listing, not an entitlement list, so a model the key can actually invoke but that is absent from the listing hard-failed the run.The new
providerBaseUrlIsCustomhelper insrc/config/constants.tscompares the resolved base URL againstProviderConfig.baseURL, normalizing whitespace and trailing slashes. It also removes the duplicated override-detection logic that had been reimplemented at the call site, so it can no longer drift fromresolveProviderBaseUrl.An empty catalogue is
unknown, notunavailable.Array.isArray([])istrue, so{"object":"list","data":[]}fell straight through.some()into the hard-block path. The README documentsNVIDIA_BASE_URLfor a self-hosted or proxied gateway, and proxies such as LiteLLM or a KServe router commonly return an empty or filtered/v1/modelswhen the key lacks list scope while inference still works fine.The lookup is bounded by a 5s timeout. The fetch had no
AbortSignal. Previously it only ever contactedapi.openai.com; this feature points it at arbitrary user-supplied infrastructure. A self-hosted NIM behind a VPN that accepts the connection then stalls held every run before inference for undici's 300s default. Uses the sameAbortSignal.timeoutpattern assrc/connectors/http.ts.The catalogue URL is built from
pathname.new URL("models", ensureTrailingSlash(base))dropped the last path segment when the base URL carried a query string or fragment.Usually that 404s and degrades to
unknown, so validation silently stopped working. But if the wrong path happened to serve a different catalogue, it produced a falseunavailable. URL construction also moved inside a guard, so a base URL that cannot be parsed returnsunknowninstead of throwing out of the availability check.The thrown error carries the real reason. It previously blamed "the configured credentials" for a model that simply is not loaded on the endpoint, and discarded the
reasonfield that said so accurately.Validation
pnpm run format:checkpnpm run lint:checkpnpm run typecheckpnpm vitest run test/model-availability.test.ts test/config/constants.test.ts— 94 passedNine new tests cover each fix: the default-value-pinned base URL, the empty catalogue, the query-string base URL, the abort signal, and the
providerBaseUrlIsCustomhelper across default, restated-default, custom, no-default, and whitespace-only inputs.The full suite has 13 pre-existing failing files on this machine (parallel-load timeouts in
evals/ledger/*,test/agent/*,test/connectors/sources/git-repo.test.ts). Verified as baseline: the same 13 files fail on the parent commit with these changes stashed (31 failed tests before, 29 after, with 9 tests added). Every one of them passes when run in isolation.Reviewer reproduction
To confirm the main regression by hand, set
NVIDIA_BASE_URLto the documented hosted endpoint and check that validation stays non-authoritative:Expected:
model.availability=unknown reason=The NVIDIA hosted endpoint is not validated.in debug output, and the run proceeds. Before this change, the hosted catalogue was queried and could block the run.