JSON Errors / Swift
Swift DecodingError: keyNotFound / typeMismatch / valueNotFoundHow to Fix: Swift DecodingError: keyNotFound / typeMismatch / valueNotFound
JSONDecoder threw one of four DecodingError cases, and the case names the problem: keyNotFound (the JSON lacks a key your struct requires), valueNotFound (the value is null but the property is non-optional), typeMismatch (a string arrived where you declared Int), or dataCorrupted (the input is not valid JSON at all).
Each case carries a codingPath - the exact route to the failing field - and a debugDescription. Reading these two fields is the entire diagnosis; most frustration with Codable comes from not printing them.
Common causes
1. keyNotFound / valueNotFound - required vs actually-optional
The API omits or nulls a field your struct declares as non-optional.
struct User: Codable { let nickname: String }
// {"name": "Ada"} -> keyNotFound(nickname)struct User: Codable { let nickname: String? } // absent or null -> nil2. typeMismatch - numbers sent as strings
APIs that serialize ids or amounts as "42" clash with Int/Double properties - common with PHP and older backends.
3. dataCorrupted - not JSON, or a date strategy mismatch
The body is HTML/empty, or a Date property is decoded without setting the matching dateDecodingStrategy.
How to fix it
do {
let order = try JSONDecoder().decode(Root.self, from: data)
} catch let DecodingError.keyNotFound(key, context) {
print("missing key '(key.stringValue)' at (context.codingPath.map(\.stringValue))")
} catch let DecodingError.typeMismatch(type, context) {
print("expected (type) at (context.codingPath.map(\.stringValue)): (context.debugDescription)")
} catch {
print("decode failed:", error)
}struct FlexibleInt: Codable {
let value: Int
init(from decoder: Decoder) throws {
let c = try decoder.singleValueContainer()
if let i = try? c.decode(Int.self) { value = i }
else { value = Int(try c.decode(String.self)) ?? 0 }
}
}Frequently asked questions
The error says dataCorrupted but my JSON is valid. Why?
dataCorrupted is also thrown by value-level failures: a Date that does not match the dateDecodingStrategy, or a URL/Decimal that cannot be constructed from the string. Check context.codingPath - if it points at a date field, set decoder.dateDecodingStrategy to match the format.
How do I make decoding tolerant of a bad element in an array?
Decode elements as a lossy wrapper: try? container.decode(Element.self) inside a custom init, collecting successes and skipping failures (the "LossyCodableList" pattern). Default Codable is all-or-nothing per document - one bad element fails the whole array.
Why does everything work in the simulator but fail with real API data?
Fixtures drift from production: staging returns every field populated while production omits optionals or nulls them. Decode a captured production payload in a unit test - the codingPath in the failure tells you which struct property to relax.
Last updated:
Related JSON errors
You might also need
Free and in-browser, like everything on JSON Console. Browse all tools →