What happens when I access a Dict key that doesn't exist in EK9?
← Collections and Data Structures · Ref: Q129
EK9 Dict uses safe access patterns instead of throwing exceptions for missing keys. This eliminates KeyNotFoundException and NullPointerException patterns.
NO EXCEPTIONS ON MISSING KEYS
EK9 never throws exceptions for missing keys. Instead, getOrDefault always returns a value, and contains checks for key existence.
GETORDEFAULT PATTERN
Provide a fallback value for missing keys:
value <- config.getOrDefault("host", "localhost")
If "host" exists, returns its value. If missing, returns "localhost". Always returns a set value.
CONTAINS CHECK
Check if a key exists before accessing:
if config contains "port" stdout.println("Port is configured")
The contains operator uses the key type for lookup.
COMBINING CONTAINS AND GETORDEFAULT
Use contains when you need conditional logic based on key existence:
if config contains "debug" debug <- config.getOrDefault("debug", "false") stdout.println(debug)
Use getOrDefault directly when you always want a value.
SAFE ITERATION
for-in on a Dict iterates over DictEntry pairs:
for entry in config stdout.println($entry)
This always works safely, even on an empty Dict.
See Q46 for Dict basics. See Q90 for Dict operations. See Q29 for unset variables and tri-state semantics. See Q126 for choosing the right collection type. See Q139 for EK9's error handling philosophy (safe returns vs exceptions). See Q260 for Dict key type requirements.
Example
defines module qa.collections.missingdictkey defines program MissingDictKeyDemo() stdout <- Stdout() config <- {"host": "localhost", "port": "8080", "debug": "true"} // === GETORDEFAULT === host <- config.getOrDefault("host", "unknown") stdout.println(`Host: ${host}`) // Missing key returns the default timeout <- config.getOrDefault("timeout", "30") stdout.println(`Timeout: ${timeout}`) // === CONTAINS CHECK === if config contains "port" stdout.println("Port is configured") if not (config contains "missing") stdout.println("Missing key not found") // === GETORDEFAULT WITH ISSET CHECK === debug <- config.getOrDefault("debug", "false") stdout.println(`Debug: ${debug}`) // Using contains for existence check if config contains "debug" stdout.println("Debug is configured") if not (config contains "nonexistent") stdout.println("Nonexistent key not in dict") // === SAFE ITERATION === for entry in config stdout.println(`Entry: ${entry}`) // === EMPTY DICT IS SAFE === emptyDict <- Dict() of (String, String) noValue <- emptyDict.getOrDefault("key", "default") stdout.println(`From empty: ${noValue}`)
Common mistakes
E50060 — EK9 Dict has no get() method. Use getOrDefault(key, default) which always returns a value, eliminating null/missing-key exceptions. See ek9 -h E50060 for details.
Incorrect:
host <- config.get("host")
Correct:
host <- config.getOrDefault("host", "unknown")
E50060 — EK9 uses the 'contains' operator for key existence checks, not a containsKey() method. See ek9 -h E50060 for details.
Incorrect:
if config.containsKey("port")
Correct:
if config contains "port"
E50060 — EK9 Dict has no get() method. Use getOrDefault(key, default) which always returns a value. See ek9 -h E50060 for details.
Incorrect:
timeout <- config.get("timeout")
Correct:
timeout <- config.getOrDefault("timeout", "30")
E07620 — The contains operator checks for key existence using the Dict's key type. Passing an Integer to a Dict of (String, String) fails because the contains operator is not defined for that type combination. Use the correct key type. See ek9 -h E07620 for details.
Incorrect:
if config contains 42
Correct:
if config contains "port"
E50060 — getOrDefault requires two arguments: the key and a default value. Omitting the default value causes a parameter mismatch. See ek9 -h E50060 for details.
Incorrect:
debug <- config.getOrDefault("debug")
Correct:
debug <- config.getOrDefault("debug", "false")
E50060 — The first argument to getOrDefault must match the Dict's key type. Passing an Integer key to a Dict of (String, String) causes a parameter type mismatch. See ek9 -h E50060 for details.
Incorrect:
noValue <- emptyDict.getOrDefault(42, "default")
Correct:
noValue <- emptyDict.getOrDefault("key", "default")
Other ways to ask this
- How do I safely get a value from a Dict in EK9?
- Does EK9 throw exceptions for missing dictionary keys?
- How do I check if a key exists in a Dict in EK9?
Coming from another language?
Java: map.get() returns null, map.getOrDefault() since Java 8, map.containsKey(). Python: dict[key] throws KeyError, dict.get(key, default) is safe. JavaScript: obj[key] returns undefined. Rust: map.get() returns Option<&V>. Go: val, ok := map[key] two-value return. EK9: getOrDefault always returns a value, contains checks existence, safe iteration with for-in, no exceptions thrown.
Keywords: access, dict, exception, contains, default, safe, collection, data-structure, missing, key, getOrDefault, lookup