{"record":{"id":"afeea8b50b21247b","repo":"clockworklabs/SpacetimeDB","slug":"cannot-serialize-refs-without-a-typespace","errorCode":null,"errorMessage":"cannot serialize refs without a typespace","messagePattern":"cannot serialize refs without a typespace","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"crates/bindings-typescript/src/lib/algebraic_type.ts","lineNumber":131,"sourceCode":"  I16: { tag: 'I16' } as const,\n  U16: { tag: 'U16' } as const,\n  I32: { tag: 'I32' } as const,\n  U32: { tag: 'U32' } as const,\n  I64: { tag: 'I64' } as const,\n  U64: { tag: 'U64' } as const,\n  I128: { tag: 'I128' } as const,\n  U128: { tag: 'U128' } as const,\n  I256: { tag: 'I256' } as const,\n  U256: { tag: 'U256' } as const,\n  F32: { tag: 'F32' } as const,\n  F64: { tag: 'F64' } as const,\n  makeSerializer(\n    ty: AlgebraicTypeType,\n    typespace?: TypespaceType\n  ): Serializer<any> {\n    if (ty.tag === 'Ref') {\n      if (!typespace)\n        throw new Error('cannot serialize refs without a typespace');\n      while (ty.tag === 'Ref') ty = typespace.types[ty.value];\n    }\n    switch (ty.tag) {\n      case 'Product':\n        return ProductType.makeSerializer(ty.value, typespace);\n      case 'Sum':\n        return SumType.makeSerializer(ty.value, typespace);\n      case 'Array':\n        if (ty.value.tag === 'U8') {\n          return serializeUint8Array;\n        } else {\n          const serialize = AlgebraicType.makeSerializer(ty.value, typespace);\n          return (writer, value) => {\n            writer.writeU32(value.length);\n            for (const elem of value) {\n              serialize(writer, elem);\n            }\n          };","sourceCodeStart":113,"sourceCodeEnd":149,"githubUrl":"https://github.com/clockworklabs/SpacetimeDB/blob/524b4487d949b61a07d4f39c862d1290259dfd20/crates/bindings-typescript/src/lib/algebraic_type.ts#L113-L149","documentation":"AlgebraicType.makeSerializer(ty, typespace) builds a serializer for a SATS algebraic type. A Ref type is only an index into a typespace (the array of types emitted with a module's schema), so when ty.tag === 'Ref' and no typespace was passed there is no way to resolve the referenced type. The library throws instead of guessing and emitting corrupt bytes.","triggerScenarios":"Calling AlgebraicType.makeSerializer({ tag: 'Ref', value: n }) or AlgebraicType.serializeValue(writer, refTy, value) without the second typespace argument; hand-building serializers from module schema metadata and dropping the typespace when recursing into Product/Sum elements.","commonSituations":"Writing custom row encoders over raw AlgebraicType metadata; porting code from an older bindings version where the typespace argument was not threaded through recursive calls; passing only the inner type of a Ref-containing product while forgetting the containing schema's typespace.","solutions":["Pass the module's typespace as the second argument: AlgebraicType.makeSerializer(ty, typespace)","Or dereference the ref yourself first: while (ty.tag === 'Ref') ty = typespace.types[ty.value]","Prefer the schema-generated table/reducer bindings, which always carry the typespace"],"exampleFix":"// before\nconst ser = AlgebraicType.makeSerializer(ty); // ty = { tag: 'Ref', value: 3 } -> throws\n\n// after\nconst ser = AlgebraicType.makeSerializer(ty, schema.typespace);","handlingStrategy":"validation","validationCode":"function assertSerializableType(ty: AlgebraicTypeType, typespace?: TypespaceType): void {\n  if (ty.tag === 'Ref' && !typespace) {\n    throw new Error(`Ref type (index ${ty.value}) cannot be serialized without a typespace`);\n  }\n}\n// assertSerializableType(ty, typespace) before makeSerializer","typeGuard":"const isRefType = (ty: AlgebraicTypeType): ty is { tag: 'Ref'; value: number } =>\n  ty.tag === 'Ref';","tryCatchPattern":null,"preventionTips":["Always thread the typespace through recursive serializer-building code","Prefer schema-generated bindings over hand-built serializers","Treat a Ref type without a typespace as a programming bug: fail fast in dev with a clear message"],"tags":["serialization","typescript","spacetimedb","typespace","schema"],"backgroundTag":"type-resolution-failed","analyzedSha":"524b4487d949b61a07d4f39c862d1290259dfd20","analyzedAt":"2026-08-16T23:58:54.611Z","schemaVersion":2},"datasetVersion":"2026-08-17T04:17:16.089Z"}