🏺 fix: Preserve Last Good Config on Reload - #16383
lia-by-librechat[bot] wants to merge 1 commit into
Conversation
|
Ready for review at |
|
@codex review |
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 36fb24a6c9
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| } | ||
| } | ||
|
|
||
| setMaxSubagents(getConfiguredMaxSubagents(loadedConfig)); |
There was a problem hiding this comment.
Defer committing the subagent cap until reload publication
When a reload file validates but a later stage rejects—for example, AppService, setCachedTools, or cache.set in loadAndCacheBaseConfig—this call has already replaced the process-global maximum and considers the loader successful, so the finally block does not restore it. The service then returns lastGoodBaseConfig, but agent and model-spec validators read getMaxSubagents() and enforce the rejected file's limit, potentially accepting more subagents than the preserved configuration permits or rejecting previously valid requests. Keep the cap provisional until the complete base configuration is published, or restore it from the service's failure path.
AGENTS.md reference: AGENTS.md:L80-L86
Useful? React with 👍 / 👎.
| defaultEndpoint != null && | ||
| defaultEndpoint !== 'custom' && | ||
| defaultEndpoint !== Providers.OPENROUTER |
There was a problem hiding this comment.
Keep empty OpenRouter endpoint values on the defaulting path
For an OpenRouter endpoint whose customParams.defaultParamsEndpoint is an empty string, this now returns true, whereas the previous truthiness check treated the value as absent and replaced it with openrouter. Because endpointSchema permits any string, such an existing configuration passes schema validation but now reaches parseCustomParams, is rejected as an invalid endpoint, and can terminate startup. Preserve the prior falsy-value behavior or make the schema reject and migrate this value explicitly.
AGENTS.md reference: AGENTS.md:L42-L46
Useful? React with 👍 / 👎.
Summary
A later read of
librechat.yamlcurrently reuses the startup loader. If a cache invalidation lands while the local file is missing, a remoteCONFIG_PATHis unavailable, or the YAML is invalid, the live process either replaces its config with defaults or exits.This change separates startup and reload failure policy. Startup keeps its existing validation and exit behavior, while every later source, parse, validation, or enrichment failure preserves the last configuration that this process successfully served. Local files and remote HTTP(S) configuration sources follow the same safe reload path.
How it works
The custom-config reader now lives in
packages/apiwith injected local loading, path resolution, and redaction boundaries. The legacy/apimodule is only the CommonJS composition adapter.Type of change
Testing
Tested environments/configuration:
CONFIG_PATHloader pathsAutomated tests:
cd packages/api && ../../node_modules/.bin/jest src/app/service.spec.ts --coverage=false --runInBandcd api && ../node_modules/.bin/jest server/services/Config/loadCustomConfig.spec.js --coverage=false --runInBandcd packages/api && ../../node_modules/.bin/tsc --noEmitcd packages/api && ./node_modules/.bin/tsdownScreenshots / recordings
No user-facing change.
Risk / compatibility
Startup behavior and admin override merge precedence are unchanged. The last-good snapshot is process-local, matching the existing
APP_CONFIGcache, and this PR does not add cross-replica propagation.Checklist