bfe4cbdc2a
The normalizer writes alias keys into the entry it is given (entry['key_env'] = entry['api_key_env'] and entry[snake] = entry[camel]) while building its normalized copy. Two of its three callers — get_compatible_custom_providers and providers_dict_to_custom_providers — pass live sub-dicts straight from load_config_readonly()'s shared cache (only _custom_provider_entry_to_provider_config defends with dict(entry)). A config written with the documented camelCase / api_key_env aliases therefore gets its cached copy polluted with injected duplicate keys, violating the cache's explicit no-mutation contract; every later load_config() deepcopy inherits the duplicates, and any save_config(load_config()) flow (setup wizard, dashboard writes, model persist) writes them back to config.yaml. The aux-client TLS resolution runs this on every auxiliary client build, so the mutation also happens unlocked on worker threads against a shared object. Shallow-copy the entry up front; the function's return value is a separately-built dict, so behavior is otherwise unchanged.