{"record":{"id":"f948691288947a28","repo":"clockworklabs/SpacetimeDB","slug":"could-not-serialize-result-object-had-neither-a","errorCode":null,"errorMessage":"could not serialize result: object had neither a `ok` nor an `err` field","messagePattern":"could not serialize result: object had neither a `ok` nor an `err` field","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"crates/bindings-typescript/src/lib/algebraic_type.ts","lineNumber":672,"sourceCode":"    ) {\n      const serializeOk = AlgebraicType.makeSerializer(\n        ty.variants[0].algebraicType,\n        typespace\n      );\n      const serializeErr = AlgebraicType.makeSerializer(\n        ty.variants[0].algebraicType,\n        typespace\n      );\n\n      return (writer, value) => {\n        if ('ok' in value) {\n          writer.writeU8(0);\n          serializeOk(writer, value.ok);\n        } else if ('err' in value) {\n          writer.writeU8(1);\n          serializeErr(writer, value.err);\n        } else {\n          throw new TypeError(\n            'could not serialize result: object had neither a `ok` nor an `err` field'\n          );\n        }\n      };\n    } else {\n      let serializer = SERIALIZERS.get(ty);\n      if (serializer != null) return serializer;\n\n      const serializers: Record<string, Serializer<any>> = {};\n\n      const body = `\\\nswitch (value.tag) {\n${ty.variants\n  .map(\n    ({ name }, i) => `\\\n  case ${JSON.stringify(name!)}:\n    writer.writeByte(${i});\n    return this.${name!}(writer, value.value);`","sourceCodeStart":654,"sourceCodeEnd":690,"githubUrl":"https://github.com/clockworklabs/SpacetimeDB/blob/524b4487d949b61a07d4f39c862d1290259dfd20/crates/bindings-typescript/src/lib/algebraic_type.ts#L654-L690","documentation":"Sum types whose two variants are named exactly 'ok' (index 0) and 'err' (index 1) get a specialized serializer: it writes discriminant byte 0/1 plus the payload field. At serialize time it probes the value with 'ok' in value / 'err' in value; a value with neither field (null, {}, arrays, or mis-cased keys like Ok/Err) throws this TypeError.","triggerScenarios":"Serializing a Result-shaped sum value that is null/undefined, {}, uses different casing ({ Ok: x } or { Err: e }), or passes the payload unwrapped (value instead of { ok: value }) - e.g. inserting into a Result-typed column or calling a reducer with a Result argument.","commonSituations":"Module schema declares the variants with different casing than the TS bindings expect (exactly 'ok'/'err'); JSON payloads where the wrapper object was dropped; writing a default/undefined value to a Result column.","solutions":["Wrap the payload: serialize { ok: value } or { err: value }","Verify the variant names in the module schema are exactly ok/err (the bindings special-case those spellings)","Type-check values before insert/reducer calls so unwrapped or null payloads fail in your code, not inside the serializer"],"exampleFix":"// before\nreducers.set_result(payload); // payload = 'done' or undefined -> throws\n\n// after\nreducers.set_result({ ok: payload });\n// or\nreducers.set_result({ err: 'not permitted' });","handlingStrategy":"type-guard","validationCode":"function isResultLike(v: unknown): boolean {\n  return typeof v === 'object' && v !== null && ('ok' in v || 'err' in v);\n}\n// if (!isResultLike(value)) throw new TypeError('expected { ok } or { err }');","typeGuard":"type ResultLike<T = unknown, E = unknown> = { ok: T } | { err: E };\nfunction isResultLike<T, E>(v: unknown): v is ResultLike<T, E> {\n  return typeof v === 'object' && v !== null && ('ok' in v || 'err' in v);\n}","tryCatchPattern":null,"preventionTips":["Model Result values in TS as a discriminated union so the compiler rejects unwrapped payloads","Double-check the module's variant spellings are exactly ok/err when the TS side uses the special-case path","Validate external (JSON) input at the boundary before it reaches insert/reducer calls"],"tags":["serialization","typescript","spacetimedb","sum-type","result-type"],"backgroundTag":"unwrapped-result-value","analyzedSha":"524b4487d949b61a07d4f39c862d1290259dfd20","analyzedAt":"2026-08-16T23:58:54.611Z","schemaVersion":2},"datasetVersion":"2026-08-17T04:17:16.089Z"}