{"record":{"id":"dfa1ca394da60bae","repo":"apache/beam","slug":"error-encoding-pane-v-non-speculative-index-value-must-be","errorCode":null,"errorMessage":"error encoding pane %v: non-speculative index value must be equal to -1 if the pane timing is early","messagePattern":"error encoding pane (.+?): non-speculative index value must be equal to -1 if the pane timing is early","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"sdks/go/pkg/beam/core/graph/coder/panes.go","lineNumber":47,"sourceCode":"\n\tpane := byte(0)\n\tif v.IsFirst {\n\t\tpane |= 0x01\n\t}\n\tif v.IsLast {\n\t\tpane |= 0x02\n\t}\n\tpane |= byte(v.Timing << 2)\n\n\tswitch {\n\tcase (v.Index == 0 && v.NonSpeculativeIndex == 0) || v.Timing == typex.PaneUnknown:\n\t\t// The entire pane info is encoded as a single byte\n\t\tpaneByte := []byte{pane}\n\t\tw.Write(paneByte)\n\tcase v.Index == v.NonSpeculativeIndex || v.Timing == typex.PaneEarly:\n\t\t// The pane info is encoded as this byte plus a single VarInt encoded integer\n\t\tif v.Timing == typex.PaneEarly && v.NonSpeculativeIndex != -1 {\n\t\t\treturn fmt.Errorf(\"error encoding pane %v: non-speculative index value must be equal to -1 if the pane timing is early\", v)\n\t\t}\n\t\tpaneByte := []byte{pane | 1<<4}\n\t\tw.Write(paneByte)\n\t\tEncodeVarInt(v.Index, w)\n\tdefault:\n\t\t// The pane info is encoded as this byte plus two VarInt encoded integer\n\t\tpaneByte := []byte{pane | 2<<4}\n\t\tw.Write(paneByte)\n\t\tEncodeVarInt(v.Index, w)\n\t\tEncodeVarInt(v.NonSpeculativeIndex, w)\n\t}\n\treturn nil\n}\n\n// NewPane initializes the PaneInfo from a given byte.\n// By default, PaneInfo is assigned to NoFiringPane.\nfunc NewPane(b byte) typex.PaneInfo {\n\tpn := typex.NoFiringPane()","sourceCodeStart":29,"sourceCodeEnd":65,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/go/pkg/beam/core/graph/coder/panes.go#L29-L65","documentation":"EncodePane validates pane metadata before encoding: when the pane timing is typex.PaneEarly, the NonSpeculativeIndex must be exactly -1 (the sentinel for 'no speculative index'). This error means a typex.PaneInfo value violates that invariant, so the coder refuses to serialize it rather than producing a corrupt stream.","triggerScenarios":"Constructing a typex.PaneInfo with Timing set to PaneEarly but NonSpeculativeIndex set to something other than -1, then calling panes.EncodePane (directly or via Encode/EncodeWindowedValueHeader/timer encoding paths).","commonSituations":"Custom pane bookkeeping in a runner or transform that tracks speculative indexes while also marking early panes; hand-built PaneInfo in tests; a runner bug emitting panes with default 0 index on early firings.","solutions":["Set NonSpeculativeIndex to -1 when creating PaneInfo values with Timing == PaneEarly.","Use typex.PaneInfo constructors/helpers instead of struct literals so invariants hold.","Audit custom runner/transform code that builds panes and reset the index for early panes.","If this arises from the Beam runtime itself, file an issue with the Beam Go SDK with the pane value."],"exampleFix":"// before\np := typex.PaneInfo{Timing: typex.PaneEarly, Index: 0, NonSpeculativeIndex: 0}\n// after\np := typex.PaneInfo{Timing: typex.PaneEarly, Index: 0, NonSpeculativeIndex: -1}","handlingStrategy":"validation","validationCode":"func validPane(p typex.PaneInfo) bool {\n\treturn p.Timing != typex.PaneEarly || p.NonSpeculativeIndex == -1\n}","typeGuard":"func isEarlyPaneValid(p typex.PaneInfo) bool { return p.Timing != typex.PaneEarly || p.NonSpeculativeIndex == -1 }","tryCatchPattern":"if err := panes.EncodePane(p, w); err != nil {\n\tif strings.Contains(err.Error(), \"non-speculative index\") { log.Printf(\"invalid pane %v\", p) }\n\treturn err\n}","preventionTips":["Always build PaneInfo via typex helpers rather than raw struct literals.","Enforce NonSpeculativeIndex == -1 for early-timing panes in custom runner code.","Add unit tests round-tripping EncodePane/DecodePane for every pane timing."],"tags":["go","beam","serialization","windowing","validation"],"backgroundTag":"invalid-argument-value","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}