Expected to decode String but found a dictionary instead


I am getting the following error

Error in decoding: typeMismatch(Swift.String, Swift.DecodingError.Context(codingPath: [CodingKeys(stringValue: "study_ref", intValue: nil), _JSONKey(stringValue: "Index 0", intValue: 0), CodingKeys(stringValue: "study_state", intValue: nil)], debugDescription: "Expected to decode String but found a dictionary instead.", underlyingError: nil))

My code is

struct StudyDetails: Codable {
let id: String?
let object_type: String?
let state: String?
let title: String?
let brief_summary: String?
let detailed_description: String?
let start_date: String?
let end_date: String?
let study_type: String?
let time_frame: String?
let measure: String?
let enrollment: String?
let sponsor: String?
//let condition_ref: [String]?
let sampling_method: String?
let criteria: String?
let gender: String?
let minimum_age: Int?
let maximum_age: Int?

enum CodingKeys: String, CodingKey {
    case object_type, state, title, brief_summary, detailed_description, start_date, end_date, study_type, time_frame, measure, enrollment, sponsor, sampling_method, criteria, gender, minimum_age, maximum_age
    case id = "_id"


struct StudyRef: Codable {
let study_id: String?
var study_state: String?
let study_details: StudyDetails?

enum CodingKeys: String, CodingKey {
    case study_id, study_state, study_details


struct StudyData: Codable {
let _id: String?
let object_type: String?
let age: String?
let participant_id: String?
let date_informed_consent: String?
let sex: String?
let race: String?
let _etag: String?
let study_ref: [StudyRef]?

enum CodingKeys: String, CodingKey {
    case _id, object_type, age, participant_id, date_informed_consent, sex, race, _etag, study_ref


Json is

"_id": {
"$oid": "61886d21d91087e07b6f6aff"
"object_type": "patient",
"age": "52",
"participant_id": "YYj7zeese8gerbJcNO9Nx8vWnPL2",
"date_informed_consent": "{"$date":'2021-08-17T05:00:00.000Z'}",
"sex": "Male",
"race": "Unknown",
"_etag": {
"$oid": "61886d208f51ea289d3d70ef"
"study_ref": [
"study_id": "61833a654648a1695aff845d",
"study_state": "INCLUDED"

Study Details are not defined in the JSON data that I am working with. Is the error because of that?

You may put ``` around code fragments to have it formatted nicely.

Looks like autogenerated JSON to me (CoreData?). Normal jsons are simpler and more "flat". You either change your JSON's (preferably), or if you absolutely can't do that - then you change your data structure accordingly to match this JSON.

import Foundation

struct S1: Codable {
    struct Id: Codable {
        var oid: String
        enum CodingKeys: String, CodingKey {
            case oid = "$oid"
    let _id: Id
    let object_type: String?

struct S2: Codable {
    let _id: String
    let object_type: String?

let s1 = #"{"_id": {"$oid": "61886d21d91087e07b6f6aff"},"object_type": "patient"}"#
let s2 = #"{"_id": "61886d21d91087e07b6f6aff","object_type": "patient"}"#

func test() {
    let data1 = s1.data(using: .utf8)!
    let data2 = s2.data(using: .utf8)!
    let v1 = try! JSONDecoder().decode(S1.self, from: data1)
    let v2 = try! JSONDecoder().decode(S2.self, from: data2)


Also you may put more custom code to keep the data structure flat while manually decoding that JSON - more work.

I'd recommend you to take a step back and figure out how to generate that JSON differently (without $oid & nested stuff) - to not have this problem in the first place.

Thank you @tera. Appreciate your response. I found the problem. I was using incorrect URL in the code vs what I was using in the browser to check json response. After fixing the correct URL everything works fine. Thanks again.

Kodable is useful for loading nested json into a flat structure