# Decoding JSON fails on iOS 17: "Number \<...\> is not representable in Swift"

**URL:** <https://forums.swift.org/t/decoding-json-fails-on-ios-17-number-is-not-representable-in-swift/67546>\
**Category:** Using Swift\
**Tags:** codable, decodable, ios17\
**Created:** [September 27, 2023, 10:17am UTC](https://forums.swift.org/t/decoding-json-fails-on-ios-17-number-is-not-representable-in-swift/67546 "2023-09-27T10:17:02Z")\
**Posts on this page:** 16\
**Page:** 1

<div class="post-metadata">

**Author:** ![tikitu](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/tikitu/32/4635_2.png) [@tikitu](https://forums.swift.org/u/tikitu)\
**Post date:** [September 27, 2023, 10:17am UTC](https://forums.swift.org/t/decoding-json-fails-on-ios-17-number-is-not-representable-in-swift/67546/1 "2023-09-27T10:17:03Z")

</div>

Hi folks,

I'm getting failures decoding json on iOS 17 that was successful on previous versions. The error is complaining that a number in the JSON is not representable in Swift, e.g.

```swift
dataCorrupted(
  Swift.DecodingError.Context(
    codingPath: [], 
    debugDescription: "The given data was not valid JSON.", 
    underlyingError: Optional(Error 
        Domain=NSCocoaErrorDomain 
        Code=3840 
        "Number 18.181818181818183 is not representable in Swift." 
        UserInfo={NSDebugDescription=Number 18.181818181818183 is not representable in Swift.})))

```

I imagine this is a float/double-representation issue -- possibly previous releases would silently truncate the value, I haven't checked back yet to be sure. It seems the right long-term fix is for me to get the backend to truncate its output to some more sensible precision.

But in the short term, is there anything I can change on the decoding/client side to get this through? I'm perfectly willing to lose precision in decoding, as compared to failing the entire JSON-blob parse.

---

<div class="post-metadata">

**Author:** ![sveinhal](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/sveinhal/32/3992_2.png) [@sveinhal](https://forums.swift.org/u/sveinhal)\
**Post date:** [September 27, 2023, 10:36am UTC](https://forums.swift.org/t/decoding-json-fails-on-ios-17-number-is-not-representable-in-swift/67546/2 "2023-09-27T10:36:18Z")

</div>

I guess you can change your models from:

```swift
struct Model: Decodable {
  //var number: Float
  var number: MyFloat
}

```

And then create a custom decoding for your numbers:

```swift
struct MyFloat: Decodable {
  var value: Float

  init(from decoder: Decoder) throws {
    let container = try decoder.singleValueContainer()
    let stringValue = try container.decode(String.self)
    // use whatever method to convert the string into a number
    self.value = ...
  }
}

```

I guess you could also make a property wrapper, so you don't have to change all call sites to `model.number.value`.

```swift
struct Model: Decodable {
  @Truncating var number: Float
}

@propertyWrapper
struct Truncating<F: FloatingPoint>: Decodable {
  var wrappedValue: F
  
  init(from decoder: Decoder) throws {
    let container = try decoder.singleValueContainer()
    let stringValue = try container.decode(String.self)
    // use whatever method to convert the string into a number
    self.wrappedValue = ...
  }
}

```

Not tested

---

<div class="post-metadata">

**Author:** ![STREGA](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/strega/32/37366_2.png) [@STREGA](https://forums.swift.org/u/STREGA)\
**Post date:** [September 27, 2023, 10:58am UTC](https://forums.swift.org/t/decoding-json-fails-on-ios-17-number-is-not-representable-in-swift/67546/3 "2023-09-27T10:58:44Z")

</div>

Did you already try changing the property for that decoded value from Float to Double?  
That value won't fit into a Float but it should fit into a Double.

---

<div class="post-metadata">

**Author:** ![tikitu](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/tikitu/32/4635_2.png) [@tikitu](https://forums.swift.org/u/tikitu)\
**Post date:** [September 27, 2023, 11:10am UTC](https://forums.swift.org/t/decoding-json-fails-on-ios-17-number-is-not-representable-in-swift/67546/4 "2023-09-27T11:10:45Z")

</div>

I did try switching Float -\> Double, I get the same error. And, _extremely_ weirdly, I also get the same problem with a much lower-precision value: `"Number 18.18 is not representable in Swift."`

That's bonkers enough that I'm looking elsewhere in my stack to see if something completely off the radar is behaving oddly.

---

<div class="post-metadata">

**Author:** ![STREGA](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/strega/32/37366_2.png) [@STREGA](https://forums.swift.org/u/STREGA)\
**Post date:** [September 27, 2023, 11:18am UTC](https://forums.swift.org/t/decoding-json-fails-on-ios-17-number-is-not-representable-in-swift/67546/5 "2023-09-27T11:18:16Z")

</div>

I can confirm Floats and Double do decode properly in Swift 5.9 (Xcode 15).  
The error "The given data was not valid JSON." seems to contradict the number thing. I suspect the number error is just the parser moving on, but the JSON is might be malformed in some way and that's the real issue.

---

<div class="post-metadata">

**Author:** ![tikitu](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/tikitu/32/4635_2.png) [@tikitu](https://forums.swift.org/u/tikitu)\
**Post date:** [September 27, 2023, 11:24am UTC](https://forums.swift.org/t/decoding-json-fails-on-ios-17-number-is-not-representable-in-swift/67546/6 "2023-09-27T11:24:21Z")

</div>

Thanks for the custom-decoding suggestion. Signs are increasingly pointing to something else being the _real_ problem and the number issue just being a knock-on consequence, but I appreciate the suggestion.

---

<div class="post-metadata">

**Author:** ![tikitu](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/tikitu/32/4635_2.png) [@tikitu](https://forums.swift.org/u/tikitu)\
**Post date:** [September 27, 2023, 2:40pm UTC](https://forums.swift.org/t/decoding-json-fails-on-ios-17-number-is-not-representable-in-swift/67546/7 "2023-09-27T14:40:13Z")

</div>

Found the cause. It _is_ a change in behaviour between iOS 16 and 17, but a rather subtle one that shortcuts in my own code happen to turn into the mess you see above.

The change in behaviour is, `SingleValueDecodingContainer.decode(Int.self)` when decoding a JSON literal such as `18.18` used to throw a `DecodingError.dataCorrupted` (saying "parsed JSON number \<18.18\> does not fit in Int"); it now throws a `JSONError.numberIsNotRepresentableInSwift`.

Mostly that's fine, because mostly when you call `decode(Int.self)` the kind of failure doesn't much matter to you. But I was using that call as a "probe" to see _if_ I could decode an Int, and catching specific error cases that I knew about. Which didn't include this one, so my retry logic for when the probe fails didn't run. Entirely my bad, as the contract doesn't make any claims whatsoever about what errors may be thrown on failure.

The error in my code is interesting in light of the ongoing discussion of [typed throws](https://forums.swift.org/t/pitch-n-1-typed-throws/67496) over on Evolution: I was treating an entirely untyped throw _as if_ I had the safety guarantees of a typed throw.

> **Why would you want to do that?!**
>
> (You may ask why on earth I needed to do that. Story too long for this margin to contain, but I'm using it to capture arbitrary JSON blobs as a sub-part of a generally strongly-typed Codable model. Its _a_ solution, definition not the _only_ solution, and very likely not _the best_ solution either.)

---

<div class="post-metadata">

**Author:** ![Jon\_Shier](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/jon_shier/32/921_2.png) [@Jon\_Shier](https://forums.swift.org/u/Jon_Shier)\
**Post date:** [September 27, 2023, 4:26pm UTC](https://forums.swift.org/t/decoding-json-fails-on-ios-17-number-is-not-representable-in-swift/67546/8 "2023-09-27T16:26:41Z")

</div>

This logic is in [Sources/FoundationEssentials/JSON/JSONDecoder.swift](https://github.com/apple/swift-foundation/blob/b14c22bc84b536e86e7ac70341b90dcbd8ad4229/Sources/FoundationEssentials/JSON/JSONDecoder.swift#L938), which appears to only throw `numberIsNotRepresentableInSwift`, which isn't a good error in cases where the user is simply trying to decode the wrong type. You may want to file an issue on that repo with a link to any feedback you've filed.

---

<div class="post-metadata">

**Author:** ![tera](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/tera/32/38201_2.png) [@tera](https://forums.swift.org/u/tera)\
**Post date:** [September 27, 2023, 5:06pm UTC](https://forums.swift.org/t/decoding-json-fails-on-ios-17-number-is-not-representable-in-swift/67546/9 "2023-09-27T17:06:20Z")

</div>

Nice find, indeed a subtle change.

I guess your implementation would tolerate decoding, say, `18.0` or even `18.0000000000000000123` as `Int`.

---

<div class="post-metadata">

**Author:** ![Skwiggs](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/skwiggs/32/34196_2.png) [@Skwiggs](https://forums.swift.org/u/Skwiggs)\
**Post date:** [March 6, 2024, 1:23pm UTC](https://forums.swift.org/t/decoding-json-fails-on-ios-17-number-is-not-representable-in-swift/67546/11 "2024-03-06T13:23:58Z")

</div>

How do you catch a `let error as JSONError`?  
I keep getting `"Cannot find type 'JSONError' in scope"` and I don't know what else to import other than `Foundation` 🤔

On another note, that typed-throws proposal is 🤩

---

<div class="post-metadata">

**Author:** ![tera](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/tera/32/38201_2.png) [@tera](https://forums.swift.org/u/tera)\
**Post date:** [March 6, 2024, 8:08pm UTC](https://forums.swift.org/t/decoding-json-fails-on-ios-17-number-is-not-representable-in-swift/67546/12 "2024-03-06T20:08:12Z")

</div>

> [@Skwiggs](#):
>
> JSONError

Is that your own type?

---

<div class="post-metadata">

**Author:** ![Skwiggs](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/skwiggs/32/34196_2.png) [@Skwiggs](https://forums.swift.org/u/Skwiggs)\
**Post date:** [March 7, 2024, 8:51am UTC](https://forums.swift.org/t/decoding-json-fails-on-ios-17-number-is-not-representable-in-swift/67546/13 "2024-03-07T08:51:03Z")

</div>

Nope, it's from Foundation as @tikitu mentioned 😛

---

<div class="post-metadata">

**Author:** ![tera](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/tera/32/38201_2.png) [@tera](https://forums.swift.org/u/tera)\
**Post date:** [March 7, 2024, 12:12pm UTC](https://forums.swift.org/t/decoding-json-fails-on-ios-17-number-is-not-representable-in-swift/67546/14 "2024-03-07T12:12:22Z")

</div>

I can't find it in public Foundation interfaces so it must be a private type → we are not supposed to use it.

---

<div class="post-metadata">

**Author:** ![Skwiggs](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/skwiggs/32/34196_2.png) [@Skwiggs](https://forums.swift.org/u/Skwiggs)\
**Post date:** [March 7, 2024, 3:03pm UTC](https://forums.swift.org/t/decoding-json-fails-on-ios-17-number-is-not-representable-in-swift/67546/15 "2024-03-07T15:03:57Z")

</div>

Yeah, hence my comment... I was trying to catch it because it currently messes with some of my decoding implementations... 😕

---

<div class="post-metadata">

**Author:** ![tera](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/tera/32/38201_2.png) [@tera](https://forums.swift.org/u/tera)\
**Post date:** [March 7, 2024, 3:07pm UTC](https://forums.swift.org/t/decoding-json-fails-on-ios-17-number-is-not-representable-in-swift/67546/16 "2024-03-07T15:07:49Z")

</div>

You want to catch just that error, instead of catching all errors?

I'd do something like this:

```swift
try {
    ...
} catch {
    let error = error as NSError
    print(error)
    // analyse these and act accordingly:
    error.code
    error.domain
    error.userInfo
}

```

---

<div class="post-metadata">

**Author:** ![emrdgrmnci](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/emrdgrmnci/32/45387_2.png) [@emrdgrmnci](https://forums.swift.org/u/emrdgrmnci)\
**Post date:** [December 4, 2024, 6:52pm UTC](https://forums.swift.org/t/decoding-json-fails-on-ios-17-number-is-not-representable-in-swift/67546/17 "2024-12-04T18:52:13Z")

</div>

I’m still experiencing the same issue on VisionOS 2.1, but it appears that there’s no problem on iOS 18.1 with the exact same data.

> Fetching Data Error dataCorrupted(Swift.DecodingError.Context(codingPath: , debugDescription: "The given data was not valid JSON.", underlyingError: Optional(Error Domain=NSCocoaErrorDomain Code=3840 "Number 3.7 is not representable in Swift." UserInfo={NSDebugDescription=Number 3.7 is not representable in Swift.})))
