{"record":{"id":"80d5cdd80677e892","repo":"go-delve/delve","slug":"wrong-number-of-bytes-for-register-s-d-80d5cd","errorCode":null,"errorMessage":"wrong number of bytes for register %s (%d)","messagePattern":"wrong number of bytes for register (.+?) \\((.+?)\\)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/proc/winutil/regs_amd64_arch.go","lineNumber":332,"sourceCode":"\tcase regnum.AMD64_R10:\n\t\tp = &ctx.R10\n\tcase regnum.AMD64_R11:\n\t\tp = &ctx.R11\n\tcase regnum.AMD64_R12:\n\t\tp = &ctx.R12\n\tcase regnum.AMD64_R13:\n\t\tp = &ctx.R13\n\tcase regnum.AMD64_R14:\n\t\tp = &ctx.R14\n\tcase regnum.AMD64_R15:\n\t\tp = &ctx.R15\n\tcase regnum.AMD64_Rip:\n\t\tp = &ctx.Rip\n\t}\n\n\tif p != nil {\n\t\tif reg.Bytes != nil && len(reg.Bytes) != 8 {\n\t\t\treturn fmt.Errorf(\"wrong number of bytes for register %s (%d)\", regnum.AMD64ToName(regNum), len(reg.Bytes))\n\t\t}\n\t\t*p = reg.Uint64Val\n\t} else if regNum == regnum.AMD64_Rflags {\n\t\tctx.EFlags = uint32(reg.Uint64Val)\n\t} else {\n\t\tif regNum < regnum.AMD64_XMM0 || regNum > regnum.AMD64_XMM0+15 {\n\t\t\treturn fmt.Errorf(\"can not set register %s\", regnum.AMD64ToName(regNum))\n\t\t}\n\t\treg.FillBytes()\n\t\tif len(reg.Bytes) > 16 {\n\t\t\treturn fmt.Errorf(\"too many bytes when setting register %s\", regnum.AMD64ToName(regNum))\n\t\t}\n\t\tcopy(ctx.FltSave.XmmRegisters[(regNum-regnum.AMD64_XMM0)*16:], reg.Bytes)\n\t}\n\treturn nil\n}\n","sourceCodeStart":314,"sourceCodeEnd":349,"githubUrl":"https://github.com/go-delve/delve/blob/a23773e6c31361e43246bc43a424ee009679b174/pkg/proc/winutil/regs_amd64_arch.go#L314-L349","documentation":"On Windows (amd64), when writing register values back to a thread's CONTEXT, Delve requires each general-purpose register slot to hold exactly 8 bytes. A Register with a non-nil Bytes field of length other than 8 is rejected.","triggerScenarios":"Calling SetRegs/WriteRegisters (e.g. via a debugger client setting a register) with a Register whose Bytes slice was populated with a length != 8, such as a 4-byte value from a 32-bit-style read or a truncated buffer.","commonSituations":"Custom tooling that constructs Register structs by hand for Windows targets; mixing register data captured from a different architecture; partial register writes where only low bytes were captured.","solutions":["Ensure reg.Bytes is exactly 8 bytes (or nil so only Uint64Val is used) before setting an amd64 general-purpose register","Call reg.FillBytes() (as the code does for XMM) to materialize Bytes from Uint64Val, then pad/truncate to 8","Verify you are not reusing register values read from a 386/x86 (4-byte) context on an amd64 target","Use the documented RPC SetRegister path instead of hand-building winutil Register structs"],"exampleFix":"// before\nreg := winutil.Register{RegNum: regnum.AMD64_Rax, Bytes: []byte{1,2,3,4}} // 4 bytes -> error\n// after\nreg := winutil.Register{RegNum: regnum.AMD64_Rax}\nreg.Uint64Val = 0x4141414141414141\nreg.FillBytes() // Bytes now len 8\n","handlingStrategy":"validation","validationCode":"// Before writing a GP register on Windows amd64:\nif reg.Bytes != nil && len(reg.Bytes) != 8 {\n    reg.FillBytes(); reg.Bytes = reg.Bytes[:8] // normalize\n}","typeGuard":"func validGPReg(reg winutil.Register) bool {\n    return reg.Bytes == nil || len(reg.Bytes) == 8\n}","tryCatchPattern":null,"preventionTips":["Always construct Register from Uint64Val and call FillBytes()","Never reuse 4-byte (386) register data on amd64 targets","Only copy register contexts captured from the same architecture"],"tags":["delve","windows","registers","amd64"],"backgroundTag":"register-size-mismatch","analyzedSha":"a23773e6c31361e43246bc43a424ee009679b174","analyzedAt":"2026-08-31T15:12:45.221Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}