{"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":"validation","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/6dee26c6efc2856793e12b148a59742964f5d783/crates/bindings-typescript/src/lib/algebraic_type.ts#L113-L149","documentation":"Thrown by SpacetimeDB's local test harness (crates/testing, call_http_route_get) when a test dispatches a GET to a path and the compiled module has no GET route for it. The harness resolves the route via module_def.match_http_route(&Method::Get, path) against the routes the module registered in its #[spacetimedb::http_router] function (a spacetimedb::http::Router built with .get(path, handler) / .post / .any). A None match becomes this error.","triggerScenarios":"Calling instance.call_http_route_get(\"/health\") in a module test when the router never registers /health, registers it only via .post(...) (GET-only lookup will not match), or registers a different path string (trailing slash, different segment, typo).","commonSituations":"Path typo between test and router; copying a POST-route test and forgetting the method; writing the test before adding the route; testing a module built from stale sources that predate the route.","solutions":["Add or fix the route in the module's #[spacetimedb::http_router] function: Router::new().get(\"/health\", health_handler).","Check the method: call_http_route_get only matches GET routes; a .post(...)-only registration will not match (use the POST-equivalent call or register with .get/.any).","Compare the exact path string (leading slash, segments, trailing slash) between the test call and the router registration.","Rebuild/re-publish the module so the harness's module_def actually contains the route."],"exampleFix":"// before (module)\n#[spacetimedb::http_router]\nfn routes() -> Router { Router::new().post(\"/hello\", hello) }\n// test\nlet body = instance.call_http_route_get(\"/hello\").await; // Err: no GET route registered for /hello\n\n// after\n#[spacetimedb::http_router]\nfn routes() -> Router { Router::new().get(\"/hello\", hello) }\nlet body = instance.call_http_route_get(\"/hello\").await?;","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"// In module tests, distinguish 'route missing' from 'handler failed':\nlet body = match instance.call_http_route_get(\"/health\").await {\n    Ok(b) => b,\n    Err(e) if e.to_string().contains(\"no GET route registered\") => panic!(\n        \"module router lacks GET /health - register it via Router::get in #[spacetimedb::http_router]\"\n    ),\n    Err(e) => panic!(\"handler failed: {e:#}\"),\n};","preventionTips":["Keep route paths as consts in the module crate and reference them from both the router and the tests.","Add the route registration first, then the test that exercises it.","During bring-up, register with .any(path, handler) so method mismatches do not fail, then narrow to .get(...)."],"tags":["spacetimedb","testing","http","routing","rust"],"backgroundTag":"route-not-found","analyzedSha":"6dee26c6efc2856793e12b148a59742964f5d783","analyzedAt":"2026-08-20T06:08:37.179Z","contentChangedAt":"2026-08-20T06:08:37.179Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}