Skip to content

Support environment variable placeholders in config validation - #3

Open
npeham wants to merge 1 commit into
mainfrom
claude/kind-wozniak-jVBvx
Open

Support environment variable placeholders in config validation#3
npeham wants to merge 1 commit into
mainfrom
claude/kind-wozniak-jVBvx

Conversation

@npeham

@npeham npeham commented Jun 2, 2026

Copy link
Copy Markdown

Summary

Adds support for environment variable placeholders (e.g., ${ENV_VAR}) in LibreChat configuration files when imported via the admin panel. The admin panel doesn't have access to deployment-specific environment variables, so placeholders would previously fail schema validation. This change sanitizes placeholders before validation and restores them afterwards, allowing full structural validation while preserving placeholder syntax.

Change Type

  • New feature (non-breaking change which adds functionality)

Implementation Details

New Utilities (src/server/utils/envPlaceholder.ts)

Two complementary functions handle placeholder management:

  • sanitizeEnvPlaceholders(value) — Recursively walks a config object and replaces any string containing ${...} with a unique, schema-safe sentinel URL (https://env-placeholder.invalid/0, etc.), returning both the sanitized config and a Map<sentinel, original> for restoration.
  • restoreEnvPlaceholders(value, placeholders) — Reverses the process by swapping sentinels back to their original placeholder strings using exact equality matching.

The sentinel format is deliberately chosen to satisfy URL validators (used in schema constraints like z.string().url()) while remaining obviously invalid for actual use.

Integration (src/server/config.ts)

The parseImportedYaml server function now:

  1. Sanitizes the raw imported config before schema validation
  2. Validates the sanitized config against configSchema
  3. Restores placeholders in the validated config before returning
  4. Also restores placeholders in the fallback config if AppService fails

This ensures that configs with environment variable placeholders pass validation and are returned with their original placeholder syntax intact.

Testing

Added comprehensive unit tests in src/server/utils/envPlaceholder.test.ts:

  • Placeholder detection and sentinel replacement
  • Handling of placeholder-free configs
  • Embedded placeholders within larger strings
  • Round-trip validation (sanitize → validate → restore)
  • Integration with the real configSchema from librechat-data-provider

All tests pass and cover the core functionality and edge cases.

Checklist

  • My code adheres to this project's style guidelines
  • I have performed a self-review of my own code
  • I have commented in complex areas of my code (JSDoc on public functions)
  • My changes do not introduce new warnings
  • I have written tests demonstrating that my changes are effective
  • Local unit tests pass with my changes

https://claude.ai/code/session_015i1Rwi3ms2TbF1upWF7LbX

The YAML import validation ran the LibreChat configSchema, whose MCP url
field resolves ${ENV_VAR} placeholders against process.env before URL
validation. The admin panel doesn't have each deployment's env vars set,
so placeholders like ${MASTRA_INTERNAL_URL} stayed literal and failed
URL validation, blocking a single canonical config shared across
environments.

Sanitize the parsed config before validation by swapping every string
holding a ${...} placeholder for a unique schema-safe sentinel, then
restore the originals verbatim after validation and AppService run, so
placeholders are preserved in the imported config.

https://claude.ai/code/session_015i1Rwi3ms2TbF1upWF7LbX
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.

2 participants