Raised on LibreChat-AI#16433: LibreChat-AI#16433 (comment)
configSchema normalizes some values with zod transforms (for example .trim() on management API client bindings, .toLowerCase() on their userId, normalizeSearxngEngines), but neither librechat.yaml nor principal config overrides ever store or consume the parsed output: loadCustomConfig returns the raw YAML, and overrides are stored and merged raw. A value that passes only because its transform normalizes it therefore reaches runtime un-normalized.
What happens: a management API client binding with clientId: " billing " passes validation because .trim() yields billing, but the stored value keeps its spaces; findClientBinding compares the token's client ID with binding.clientId exactly, so every request for that client is rejected. The same applies to the value written in librechat.yaml.
Expected: values whose schema transforms them are either consumed in their parsed form (YAML and overrides alike) or rejected when the parsed output differs from the input, so validation and runtime agree.
Raised on LibreChat-AI#16433: LibreChat-AI#16433 (comment)
configSchemanormalizes some values with zod transforms (for example.trim()on management API client bindings,.toLowerCase()on theiruserId,normalizeSearxngEngines), but neitherlibrechat.yamlnor principal config overrides ever store or consume the parsed output:loadCustomConfigreturns the raw YAML, and overrides are stored and merged raw. A value that passes only because its transform normalizes it therefore reaches runtime un-normalized.What happens: a management API client binding with
clientId: " billing "passes validation because.trim()yieldsbilling, but the stored value keeps its spaces;findClientBindingcompares the token's client ID withbinding.clientIdexactly, so every request for that client is rejected. The same applies to the value written inlibrechat.yaml.Expected: values whose schema transforms them are either consumed in their parsed form (YAML and overrides alike) or rejected when the parsed output differs from the input, so validation and runtime agree.