{"record":{"id":"49704776664ca2f6","repo":"XINCGer/Unity3DTraining","slug":"spaceleft-can-only-be-called-on-codedoutputstreams","errorCode":null,"errorMessage":"SpaceLeft can only be called on CodedOutputStreams that are writing to a flat array.","messagePattern":"SpaceLeft can only be called on CodedOutputStreams that are writing to a flat array\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"NetWorkAndResources/Socket_Protobuff/Assets/Plugins/Google.Protobuf/CodedOutputStream.cs","lineNumber":754,"sourceCode":"                throw new InvalidOperationException(\"Did not write as much data as expected.\");\n            }\n        }\n\n        /// <summary>\n        /// If writing to a flat array, returns the space left in the array. Otherwise,\n        /// throws an InvalidOperationException.\n        /// </summary>\n        public int SpaceLeft\n        {\n            get\n            {\n                if (output == null)\n                {\n                    return limit - position;\n                }\n                else\n                {\n                    throw new InvalidOperationException(\n                        \"SpaceLeft can only be called on CodedOutputStreams that are \" +\n                        \"writing to a flat array.\");\n                }\n            }\n        }\n    }\n}\n","sourceCodeStart":736,"sourceCodeEnd":762,"githubUrl":"https://github.com/XINCGer/Unity3DTraining/blob/016f98412ea5e11756b286736f479b66ab6216d5/NetWorkAndResources/Socket_Protobuff/Assets/Plugins/Google.Protobuf/CodedOutputStream.cs#L736-L762","documentation":"CodedOutputStream.SpaceLeft() reports remaining writable bytes only when the stream wraps a flat byte array. If the stream wraps another Stream (output != null), there is no bounded buffer to measure, so the library throws InvalidOperationException rather than return a meaningless value.","triggerScenarios":"Calling SpaceLeft() on a CodedOutputStream constructed with a Stream (e.g. new CodedOutputStream(someStream)), or one created via CodedOutputStream.CreateStream. Only the byte[]-backed constructor supports it.","commonSituations":"Hand-rolled serialization code that checks remaining capacity before writing; code shared between array-backed and stream-backed output paths; copying examples that assume byte[] backing.","solutions":["Ensure the CodedOutputStream was constructed from a byte[] (new CodedOutputStream(byte[])) before calling SpaceLeft","Refactor to not need SpaceLeft: write directly and let the stream buffer/flush itself","Use WriteContext/WriteRawMessage APIs that handle length prefixing instead of manual capacity checks","If using a Stream, wrap it and track written bytes yourself (position vs known limit)"],"exampleFix":"// before\nvar cos = new CodedOutputStream(networkStream);\nif (cos.SpaceLeft() < 4) Flush();\n// after\nvar buffer = new byte[1024];\nvar cos = new CodedOutputStream(buffer);\nif (cos.SpaceLeft() < 4) { /* must not happen: array is fixed; flush to stream instead */ }","handlingStrategy":"validation","validationCode":"if (cos.WriteContext == null || arrayBacked) { use SpaceLeft } else { skip check }","typeGuard":"bool IsArrayBacked(CodedOutputStream cos) => cos != null && !cos.UsesStream; // construct-only knowledge; track backing yourself","tryCatchPattern":"try { space = cos.SpaceLeft(); } catch (InvalidOperationException) { space = -1; /* stream-backed */ }","preventionTips":["Track how each CodedOutputStream was constructed (byte[] vs Stream)","Avoid manual capacity math; use high-level write APIs","Wrap stream-backed writers with your own byte counter if capacity checks are needed"],"tags":["protobuf","csharp","invalid-operation"],"backgroundTag":"invalid-state-transition","analyzedSha":"016f98412ea5e11756b286736f479b66ab6216d5","analyzedAt":"2026-09-12T01:08:58.711Z","contentChangedAt":"2026-09-12T01:08:58.711Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}