{"record":{"id":"a00d413b9ad6f097","repo":"apache/beam","slug":"unable-to-decode-bool-expected-0-1-got-v","errorCode":null,"errorMessage":"unable to decode bool; expected {0, 1} got %v","messagePattern":"unable to decode bool; expected (.+?) got (.+?)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"sdks/go/pkg/beam/runners/prism/internal/engine/timers.go","lineNumber":239,"sourceCode":"\tb := d.raw[d.cursor:end]\n\td.cursor = end\n\treturn b\n}\n\n// UnusedBytes returns the remainder of bytes in the buffer that weren't yet used.\n// Multiple timers can be provided in a single timers buffer, since multiple dynamic\n// timer tags may be set.\nfunc (d *decoder) UnusedBytes() []byte {\n\treturn d.raw[d.cursor:]\n}\n\nfunc (d *decoder) Bool() bool {\n\tif b := d.Byte(); b == 0 {\n\t\treturn false\n\t} else if b == 1 {\n\t\treturn true\n\t} else {\n\t\tpanic(fmt.Sprintf(\"unable to decode bool; expected {0, 1} got %v\", b))\n\t}\n}\n\nfunc (d *decoder) Pane() typex.PaneInfo {\n\tfirst := d.Byte()\n\tpn := coder.NewPane(first & 0x0f)\n\n\tswitch first >> 4 {\n\tcase 0:\n\t\t// Result encoded in only one pane.\n\t\treturn pn\n\tcase 1:\n\t\t// Result encoded in one pane plus a VarInt encoded integer.\n\t\tindex := d.Varint()\n\t\tpn.Index = index\n\t\tif pn.Timing == typex.PaneEarly {\n\t\t\tpn.NonSpeculativeIndex = -1\n\t\t} else {","sourceCodeStart":221,"sourceCodeEnd":257,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/go/pkg/beam/runners/prism/internal/engine/timers.go#L221-L257","documentation":"decoder.Bool in the prism runner's engine decodes a single byte as a boolean, accepting only 0 (false) and 1 (true). Any other byte value means the byte stream is corrupted or misaligned relative to the coder that produced it, so the decoder panics rather than silently returning a wrong value.","triggerScenarios":"A encoded data stream (e.g. element or timer blobs from the FnAPI) contains a byte other than 0 or 1 at a position where the coder says a bool should be; typically a decoder misalignment after a previous field was read with the wrong width, or a custom/unknown coder emitting non-standard bool encodings.","commonSituations":"Mismatched coder versions between SDK language SDKs and prism, a hand-written coder emitting true/false as arbitrary bytes, or byte-stream corruption when elements are passed between runner stages.","solutions":["Verify the coder registered for the PCollection actually matches the bytes being produced (re-check the pipeline's coder inference).","Ensure both producer and consumer use the same Beam SDK version so bool coders agree on the {0,1} encoding.","Dump the raw bytes around the failure to find the misalignment point and fix the coder that wrote the extra/mis-sized field.","If using custom coders, emit bools strictly as single bytes 0 or 1."],"exampleFix":"// before (custom coder writing Go bool's textual form)\nw.Write([]byte(fmt.Sprintf(\"%v\", value))) // writes \"true\" -> first byte 't' panics\n// after\nif value { w.Write([]byte{1}) } else { w.Write([]byte{0}) }","handlingStrategy":"validation","validationCode":"// Validate the encoded byte stream before handing it to the runner\nfunc validateBoolBytes(data []byte) error {\n    for i, b := range data {\n        if b != 0 && b != 1 {\n            return fmt.Errorf(\"byte at %d is %d, not a valid bool encoding\", i, b)\n        }\n    }\n    return nil\n}","typeGuard":"func isBoolByte(b byte) bool { return b == 0 || b == 1 }","tryCatchPattern":null,"preventionTips":["Keep producer and consumer Beam SDK versions in sync","Never hand-roll bool encoding in custom coders; use the SDK's coder utilities","Validate raw element bytes when debugging cross-language pipelines"],"tags":["go","decoding","panic","coder","byte-stream"],"backgroundTag":"unexpected-response-shape","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"}