---
title: Developer override lookup
summary: OP-06 operation detail page.
status: draft
owner: Framework.NCore maintainers
last_reviewed: 2026-10-02
library: SAIF.NetCore.EnvironmentClient
reference_type: package
---

# Developer override lookup

| Field | Value |
| --- | --- |
| Owner | `TryGetDeveloperOverride`, invoked from `GetSettingFromDictionary` |
| Trigger | Every call to [Get setting value](get-setting-value.md) (via `GetConfigSetting`/`GetConfigSettingAsync` → `GetSettingFromDictionary`), once `DeveloperSettingsOverrideFile` has been set by [Initialize environment client](initialize-environment-client.md) step 7 |
| Inputs | `dictKey` (the already-composed `"{section}.{configKey}"` or bare `configKey`), `DeveloperSettingsOverrideFile` path |
| Outputs | A matching `ConfigSetting` from the override file, or no result (falls through to the loaded `Settings` dictionary) |

## Steps
1. If `DeveloperSettingsOverrideFile` is `null` (file absent, or the machine is not a developer machine, or the configured path did not exist at startup), return `false` immediately with no override.
2. Otherwise, wrap the rest of the lookup in a bare `try`/`catch { }`: **any** exception — a missing/unreadable file, malformed JSON, a `null` deserialized array, and so on — is silently swallowed, and the method falls through to `return false` as if no override file were configured at all ([BR-EC-27](../business-rules.md#br-ec-27-developer-override-file-errors-are-silently-swallowed)).
3. Read and parse the override file as a JSON array of `ConfigSetting` objects on **every** call — there is no caching of the parsed file.
4. For each parsed entry, compute its formatted key via `GetFormattedKey(setting.ConfigKey)` — `"{Section}.{Key}"` when `ConfigKey.Section` is non-empty, otherwise just `Key` — and compare it to `dictKey` using a case-insensitive (`OrdinalIgnoreCase`) match.
5. Return the **first** entry whose formatted key matches; the matched entry is returned as a whole `ConfigSetting` (not just its value), so it takes precedence over any value loaded from the Environment API for this lookup.
6. If no entry matches, return `false` and the caller proceeds to look the key up in the loaded `Settings` dictionary.
7. Because [Get setting value](get-setting-value.md) substitutes `TrackName` for a blank section before composing `dictKey`, a section-less override entry in the file must have its `ConfigKey.Section` set to the resolved track name (or be matched via the bare-key form) to be found — the lookup only operates on the already section-qualified composed key, it does not retry with alternate section candidates.
8. This lookup is reached only from the **non-secure** `GetSettingValue*` path (via `GetConfigSetting`/`GetSettingFromDictionary`); `HasSetting`, `GetSectionSettings`, and the secure-setting path never consult the override file.

## Process flow

```mermaid
flowchart TD
    A["TryGetDeveloperOverride dictKey"] --> B{DeveloperSettingsOverrideFile set?}
    B -- No --> C["No override: fall through"]
    B -- Yes --> D["Read + parse override file as JSON<br>(wrapped in catch-all try/catch)"]
    D -->|any exception| C
    D -->|parsed OK| E{"First entry whose formatted<br>key matches dictKey?"}
    E -- Yes --> F[Return matched ConfigSetting]
    E -- No --> C
```

## Sources
- `src/SAIF.NetCore.EnvironmentClient/SAIF.NetCore.EnvironmentClient/SAIF.NetCore.EnvironmentClient/BaseEnvironmentClient.cs`
