{"record":{"id":"64b5e52ab43238b5","repo":"pardeike/Harmony","slug":"position-position-count-count-buffer-length-buffer-length","errorCode":null,"errorMessage":"position({position}) + count({count}) > buffer.Length({buffer.Length})","messagePattern":"position\\((.+?)\\) \\+ count\\((.+?)\\) > buffer\\.Length\\((.+?)\\)","errorType":"exception","errorClass":"ArgumentOutOfRangeException","httpStatus":null,"severity":"error","filePath":"Harmony/Internal/ByteBuffer.cs","lineNumber":99,"sourceCode":"\t\tinternal double ReadDouble()\r\n\t\t{\r\n\t\t\tif (!BitConverter.IsLittleEndian)\r\n\t\t\t{\r\n\t\t\t\tvar bytes = ReadBytes(8);\r\n\t\t\t\tArray.Reverse(bytes);\r\n\t\t\t\treturn BitConverter.ToDouble(bytes, 0);\r\n\t\t\t}\r\n\r\n\t\t\tCheckCanRead(8);\r\n\t\t\tvar value = BitConverter.ToDouble(buffer, position);\r\n\t\t\tposition += 8;\r\n\t\t\treturn value;\r\n\t\t}\r\n\r\n\t\tvoid CheckCanRead(int count)\r\n\t\t{\r\n\t\t\tif (position + count > buffer.Length)\r\n\t\t\t\tthrow new ArgumentOutOfRangeException(nameof(count), $\"position({position}) + count({count}) > buffer.Length({buffer.Length})\");\r\n\t\t}\r\n\t}\r\n}\r\n","sourceCodeStart":81,"sourceCodeEnd":103,"githubUrl":"https://github.com/pardeike/Harmony/blob/e7872dc17008bc0ca2b3de1f53fd4120dbd7a17c/Harmony/Internal/ByteBuffer.cs#L81-L103","documentation":"ByteBuffer.CheckCanRead validates that reading 'count' bytes at the current position stays inside the underlying buffer. When position + count exceeds buffer.Length, the requested read would run past the end of the emitted IL body, so Harmony throws ArgumentOutOfRangeException for 'count'.","triggerScenarios":"Any of ReadByte/ReadBytes/ReadInt16/ReadInt32/ReadInt64/ReadSingle called when fewer than the requested bytes remain — typically a malformed or truncated method body, or a reader whose position was advanced incorrectly (e.g. misparsed exception/variable headers).","commonSituations":"Reading IL of a method from an assembly built/trimmed in an unusual way (IL2CPP, trimming, obfuscation); parsing a dynamic or abstract method with no real body; Harmony version mismatch producing a bad offset while decoding a method body.","solutions":["Ensure the target method has a real IL body (not abstract, extern, or runtime-provided) before Harmony parses it","Check that the method's assembly is not trimmed/stripped (IL2CPP, ILLink, obfuscators)","Upgrade Harmony to the latest version — earlier parsers could compute wrong offsets on exotic method bodies","Wrap the patch call and inspect the method body yourself with MethodBase.GetMethodBody() to confirm it is readable"],"exampleFix":"// before\nharmony.Patch(abstractOrNativeMethod, ...);\n// after\nif (method.IsAbstract || method.IsNative || method.GetMethodBody() is null)\n    throw new InvalidOperationException(\"Cannot patch method without IL body\");\nharmony.Patch(method, ...);","handlingStrategy":"try-catch","validationCode":"var body = method.GetMethodBody();\nif (body is null || body.GetILAsByteArray().Length == 0) throw new InvalidOperationException(\"Method has no readable IL body\");","typeGuard":null,"tryCatchPattern":"try { harmony.Patch(method, ...); }\ncatch (ArgumentOutOfRangeException ex) when (ex.ParamName == \"count\") { /* method body unreadable/truncated: skip or use alternate patching */ }","preventionTips":["Do not patch abstract, extern, or native-only methods","Check GetMethodBody() is non-null before patching","Avoid patching assemblies processed by aggressive trimming/obfuscation","Keep Harmony updated for correct IL body offsets"],"tags":["il-parsing","argumentoutofrange","buffer","harmony"],"backgroundTag":"argument-out-of-range","analyzedSha":"e7872dc17008bc0ca2b3de1f53fd4120dbd7a17c","analyzedAt":"2026-09-15T22:47:11.550Z","contentChangedAt":"2026-09-15T22:47:11.550Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}