{"record":{"id":"dd86a879b1730c75","repo":"clockworklabs/SpacetimeDB","slug":"unrecognized-extra-bytes-while-decoding-bsatn-valu","errorCode":null,"errorMessage":"Unrecognized extra bytes while decoding BSATN value","messagePattern":"Unrecognized extra bytes while decoding BSATN value","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"crates/bindings-csharp/Runtime/Http.cs","lineNumber":391,"sourceCode":"                    );\n            }\n        }\n        // Important: avoid throwing across the procedure boundary.\n        // Throwing here would trap the module (and fail the whole procedure invocation).\n        // Convert all unexpected failures (including decode errors / unexpected errno) into Result.Err instead.\n        catch (Exception ex)\n        {\n            return Result<HttpResponse, HttpError>.Err(new HttpError(ex.ToString()));\n        }\n    }\n\n    private static T FromBytes<T>(IReadWrite<T> rw, MemoryStream ms)\n    {\n        using var reader = new BinaryReader(ms);\n        var value = rw.Read(reader);\n        if (ms.Position != ms.Length)\n        {\n            throw new InvalidOperationException(\n                \"Unrecognized extra bytes while decoding BSATN value\"\n            );\n        }\n        return value;\n    }\n\n    private static HttpMethodWire ToWireMethod(HttpMethod method)\n    {\n        var m = method.Value;\n        return m switch\n        {\n            \"GET\" => new HttpMethodWire.Get(default),\n            \"HEAD\" => new HttpMethodWire.Head(default),\n            \"POST\" => new HttpMethodWire.Post(default),\n            \"PUT\" => new HttpMethodWire.Put(default),\n            \"DELETE\" => new HttpMethodWire.Delete(default),\n            \"CONNECT\" => new HttpMethodWire.Connect(default),\n            \"OPTIONS\" => new HttpMethodWire.Options(default),","sourceCodeStart":373,"sourceCodeEnd":409,"githubUrl":"https://github.com/clockworklabs/SpacetimeDB/blob/6dee26c6efc2856793e12b148a59742964f5d783/crates/bindings-csharp/Runtime/Http.cs#L373-L409","documentation":"Thrown by the module-side HTTP client (Runtime/Http.cs) when converting a host response payload into a typed value: FromBytes runs rw.Read(reader) over the response MemoryStream and then requires ms.Position == ms.Length. Leftover bytes mean the BSATN payload on the wire contains more data than the type's decoder consumed — the payload was encoded with a different (usually newer) schema than the bindings decoding it.","triggerScenarios":"Host (spacetimedb / upstream HTTP service) returns a response body serialized with a schema that has extra trailing fields relative to the T used in FromBytes<T>; version skew between the module's SpacetimeDB bindings and the host's wire format; a proxy or middleware appending bytes to the response body.","commonSituations":"Upgrading spacetimedb server but not the SpacetimeDB.BSATN/Runtime packages (or vice versa); custom response types in the HTTP helpers that drift from the actual endpoint's payload; response bodies that are not pure BSATN (e.g. concatenated frames).","solutions":["Align versions: update the SpacetimeDB bindings packages and the spacetimedb host to matching releases","Verify the type passed to the HTTP receive API is exactly the type the endpoint serializes (no extra/missing fields)","Capture the raw response bytes and compare length vs. consumed bytes to identify the trailing data","If a proxy is involved, confirm it does not append to or re-chunk the body"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"// The HTTP helpers already wrap failures as Result<HttpResponse, HttpError>;\n// pattern-match the Err side instead of letting FromBytes' throw escape:\nvar result = await SendRequest(...);\nif (result is Result<HttpResponse, HttpError>.ErrR(var httpError))\n{\n    // httpError includes the decode failure; treat trailing-byte errors as\n    // protocol corruption: reconnect or surface, never retry the same bytes\n}","preventionTips":["Upgrade bindings and spacetimedb host together, never independently","Keep response DTOs in one place and regenerate them when the endpoint schema changes","Don't pass non-BSATN bodies (JSON, concatenated frames) to the typed HTTP receive APIs"],"tags":["csharp","bsatn","http","deserialization","trailing-bytes"],"backgroundTag":"decode-extra-trailing-bytes","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"}