mutated × unstructured — blows up live on input you didn't expect

Config / Environment Drift Crash

An upgrade renames the config key the code still reads directly; the service boots fine and dies on the first request in the new environment.

01the recipe

In the wild

example.py
# SMELL: read a config key directly, assuming the deploy still provides it.
# (impure functions x library/version mismanagement)
TIMEOUT = os.environ["RPC_TIMEOUT_MS"]   # renamed to RPC_TIMEOUT_S in v2 -> KeyError
def call():
    client.invoke(timeout=int(TIMEOUT))

# RIGHT: read through validated config -- presence check + migration-aware error.
def get_timeout():
    raw = os.environ.get("RPC_TIMEOUT_S")
    if raw is None:
        raise ConfigError("RPC_TIMEOUT_S required (was RPC_TIMEOUT_MS before v2)")
    return float(raw)
Reading os.environ by key couples the code to a contract the platform can change between versions. After an upgrade renames the key, the process imports fine and throws an uncaught KeyError on first use -- in the new environment only. Centralize config access with explicit presence checks and a migration-aware error.
// observed
drifted: KeyError: 'RPC_TIMEOUT_MS' on the first request after deploy
right: a clear ConfigError naming the renamed key; no surprise mid-request
02weakness catalog

Mapped weaknesses (CWE)

On its own, this defect is catalogued by MITRE as one or more of these weaknesses. The exploitable vulnerability usually appears only when it chains or combines with another.