{"record":{"id":"2f54fec8abc99510","repo":"apache/beam","slug":"invalid-varint","errorCode":null,"errorMessage":"invalid varint","messagePattern":"invalid varint","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"sdks/go/pkg/beam/runners/prism/internal/engine/timers.go","lineNumber":144,"sourceCode":"\t\t\tif !yield(timerRet{keyBytes, tag, elms, ws}) {\n\t\t\t\treturn // Halt iteration if yield returns false.\n\t\t\t}\n\t\t\t// Otherwise continue handling the remaining bytes.\n\t\t\traw = d.UnusedBytes()\n\t\t}\n\t}\n}\n\ntype decoder struct {\n\traw    []byte\n\tcursor int\n}\n\n// Varint consumes a varint from the bytes, returning the decoded length.\nfunc (d *decoder) Varint() (l int64) {\n\tv, n := protowire.ConsumeVarint(d.raw[d.cursor:])\n\tif n < 0 {\n\t\tpanic(\"invalid varint\")\n\t}\n\td.cursor += n\n\treturn int64(v)\n}\n\n// Uint64 decodes a value of type uint64.\nfunc (d *decoder) Uint64() uint64 {\n\tdefer func() {\n\t\td.cursor += 8\n\t}()\n\treturn binary.BigEndian.Uint64(d.raw[d.cursor : d.cursor+8])\n}\n\nfunc (d *decoder) Timestamp() mtime.Time {\n\tmsec := d.Uint64()\n\treturn mtime.Time((int64)(msec) + math.MinInt64)\n}\n","sourceCodeStart":126,"sourceCodeEnd":162,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/go/pkg/beam/runners/prism/internal/engine/timers.go#L126-L162","documentation":"Prism's local decoder wraps protowire.ConsumeVarint; if the wire library reports a negative byte count, the bytes at the cursor are not a valid protobuf varint (malformed or truncated). The decoder panics because timer payload decoding cannot safely continue from a broken wire format.","triggerScenarios":"decoder.Varint called (directly or via IntervalWindow, CustomWindowLengthPrefixed, Bytes, Pane) on raw timer bytes whose next field is not a well-formed varint — truncated payloads, misaligned cursor, or a length-prefix mismatch earlier in the stream.","commonSituations":"Timer payload corruption, coder mismatches between SDK and runner (e.g. non-length-prefixed custom window coders), or SDK/runner version skew changing the timer wire format.","solutions":["Ensure window coders used with timers are length-prefixed (prism requires this; see the singleWindowExtractor setup)","Match SDK harness and prism versions to avoid timer wire-format skew","Dump the raw timer bytes at failure to check whether the payload is truncated or misaligned","If a custom coder precedes the varint, verify it consumes exactly the right number of bytes so the cursor stays aligned"],"exampleFix":"// before: non-length-prefixed custom window coder corrupts alignment\nsingleWindowExtractor = func(d *decoder) typex.Window { return d.CustomWindow() }\n// after: force length prefix so the varint cursor stays aligned\nsingleWindowExtractor = func(d *decoder) typex.Window { return d.CustomWindowLengthPrefixed() }","handlingStrategy":"validation","validationCode":"// Sanity check remaining bytes before decoding\nif len(raw) == 0 || d.cursor >= len(d.raw) {\n    return io.ErrUnexpectedEOF\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always length-prefix window coders in timer payloads","Keep harness and prism versions identical to avoid wire format skew","Hex-dump failing timer bytes to confirm truncation before filing bugs"],"tags":["go","beam","prism","protobuf","decoding","varint"],"backgroundTag":"protobuf-unmarshal-failed","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-20T03:17:13.778Z"}