_nilValue(): "Unexpected NSNull for non-Optional"

I’m seeing a crash in the wild decoding an API response from my backend: the decoding process is going through the _nilValue() implementation in the RealmCollectionValue extension, and hitting the fatalError there. Unfortunately that error doesn’t contain any type information, so I don’t know what’s causing the issue.

I’m trying to write a test to exercise the same code path, but I can’t figure out how to get there. Can someone help me understand when _nilValue() is actually invoked?

I’m on RealmSwift 10.18, running on iOS 15.

Here’s the test code that’s not working for me, if it’s helpful:

    func testListWithNullElements() throws {
        var json = """
[
    { "id": "hi" },
    { "id": "low" }
]
"""
        var list = try JSONDecoder().decode(List<NonNilModel>.self, from: json.data(using: .utf8)!) // this works
        XCTAssertEqual(list.count, 2)
        
        json = """
[
    { "id": "hi" },
    null,
    { "id": "low" }
]
"""
        list = try JSONDecoder().decode(List<NonNilModel>.self, from: json.data(using: .utf8)!) // this fails with an NSInvalidUnarchiveOperationException: "This decoder will only decode classes that adopt NSSecureCoding. Class '__SwiftValue' does not adopt it."
        XCTAssertEqual(list.count, 2)
    }
}

class NonNilModel: Object, Codable {
    @Persisted(primaryKey: true) var id: String = ""
}

Sorry, I got confused in my debugging process: the issue is actually with hitting _RealmSchemaDiscoverable 's implementation of _nilValue() , not RealmCollectionValue . Meaning, I think, it’s coming from RealmSwift.Optional.decodeOptional() . Same questions still apply: how do I reproduce this in a test, and how do I figure out what type is erroring?

For clarity, double checking you’re defining the json var like this

var json = """
    [
        { "id": "hi" },
        { "id": "low" }
    ]
    """

but then changing the definition to include a null like this?

json = """
    [
        { "id": "hi" },
        null,
        { "id": "low" }
    ]
"""

Yes, that’s right. I’ve tried some other avenues too, but they’re all pretty much just shots in the dark trying to figure out how to get _nilValue() invoked.

FWIW, I’m thinking my best bet might be to fork the repo and add some more logging in that fatalError. It really just needs a class name.