{"record":{"id":"5dd8639277d5e360","repo":"clockworklabs/SpacetimeDB","slug":"invalid-tag-value-this-state-should-be-unreachabl","errorCode":null,"errorMessage":"Invalid tag value, this state should be unreachable.","messagePattern":"Invalid tag value, this state should be unreachable\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"crates/bindings-csharp/BSATN.Codegen/Type.cs","lineNumber":654,"sourceCode":"                            {\n                                public override string ToString() =>\n                                    $\"{{m.Name}}({ SpacetimeDB.BSATN.StringUtil.GenericToString({{m.Identifier}}_) })\";\n                            }\n                        \n                        \"\"\"\n                    )\n                )\n            );\n\n            read = $$\"\"\"\n                    return reader.ReadByte() switch {\n                        {{string.Join(\n                            \"\\n            \",\n                            bsatnDecls.Select((m, i) =>\n                                $\"{i} => new {m.Identifier}({m.Identifier}{TypeUse.BsatnFieldSuffix}.Read(reader)),\"\n                            )\n                        )}}\n                        _ => throw new System.InvalidOperationException(\"Invalid tag value, this state should be unreachable.\")\n                    };\n            \"\"\";\n\n            write = $$\"\"\"\n            switch (value) {\n            {{string.Join(\n                \"\\n\",\n                bsatnDecls.Select((m, i) => $\"\"\"\n                                                            case {m.Identifier}(var inner):\n                                                                writer.Write((byte){i});\n                                                                {m.Identifier}{TypeUse.BsatnFieldSuffix}.Write(writer, inner);\n                                                                break;\n                                                \"\"\"))}}\n                        }\n            \"\"\";\n\n            getHashCode = $$\"\"\"\n            switch (this) {","sourceCodeStart":636,"sourceCodeEnd":672,"githubUrl":"https://github.com/clockworklabs/SpacetimeDB/blob/6dee26c6efc2856793e12b148a59742964f5d783/crates/bindings-csharp/BSATN.Codegen/Type.cs#L636-L672","documentation":"For tagged/variant types, the BSATN C# generator emits a read function shaped as `reader.ReadByte() switch { 0 => new VariantA(...), 1 => new VariantB(...), _ => throw new InvalidOperationException(\"Invalid tag value, this state should be unreachable.\") }`. The fallback fires when the byte stream contains a variant tag with no generated case — in practice this means the payload was encoded by a module whose variant layout differs from the client's generated bindings, or the buffer is truncated/misaligned.","triggerScenarios":"Deserializing a BSATN payload whose tag byte does not match any generated case: variants added, removed, or reordered server-side while the client runs older generated code; manually crafted BSATN fixtures with wrong tag values; truncated or offset-corrupted byte buffers.","commonSituations":"Module republished with changed enum/variant layout while clients keep stale assemblies; test harnesses hand-encoding BSATN; partial writes from a flaky websocket being fed to the parser.","solutions":["Regenerate the C# bindings from the exact module version the client connects to and redeploy","Treat variant/enum layout changes as breaking changes: migrate clients before servers, or publish under a new database name","If hand-decoding, verify tag values and byte offsets against the module schema","When versions are confirmed in sync, log raw bytes on failure to check for truncated payloads"],"exampleFix":"# before: server reorders a tagged enum's variants; client keeps old generated reader\n# tag byte 2 no longer matches any case -> InvalidOperationException\n\n# after: regenerate from the deployed module and rebuild the client\n$ spacetime generate --lang csharp --out-dir ./generated --project-path ./server\n$ dotnet build","handlingStrategy":"try-catch","validationCode":"// Round-trip test against server-encoded fixtures in CI:\n// var bytes = LoadFixture(\"player_event.bsatn\");\n// ReducerEventArgs.Read(new BinaryReader(new MemoryStream(bytes))); // must not throw\n// Regenerate fixtures whenever the module schema changes.","typeGuard":null,"tryCatchPattern":"try {\n    var evt = ReadEvent(reader);\n} catch (InvalidOperationException e) when (e.Message.Contains(\"Invalid tag value\")) {\n    // stale bindings or corrupt frame: log, reconnect, and prompt the user to update\n    Logger.LogError(\"BSATN tag mismatch — regenerate client bindings\");\n}","preventionTips":["Regenerate bindings in the same CI step that publishes the module","Treat variant/enum layout changes as breaking releases","Maintain round-trip deserialization tests with server-produced fixtures"],"tags":["csharp","bsatn","deserialization","codegen","version-mismatch"],"backgroundTag":"deserialization-version-mismatch","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"}