{"record":{"id":"a80a48d410464b90","repo":"apache/beam","slug":"runner-forgot-to-lp-this-row-coder-v","errorCode":null,"errorMessage":"Runner forgot to LP this Row Coder. %v","messagePattern":"Runner forgot to LP this Row Coder\\. (.+?)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"sdks/go/pkg/beam/runners/prism/internal/coders.go","lineNumber":382,"sourceCode":"\t\ted := pullDecoderNoAlloc(coders[ccids[0]], coders)\n\t\twd := pullDecoderNoAlloc(coders[ccids[1]], coders)\n\t\treturn func(r io.Reader) {\n\t\t\ted(r)\n\t\t\twd(r)\n\t\t}\n\tcase urns.CoderShardedKey:\n\t\tccids := c.GetComponentCoderIds()\n\t\tif len(ccids) != 1 {\n\t\t\tpanic(fmt.Sprintf(\"ShardedKey coder must have only 1 component: %s\", prototext.Format(c)))\n\t\t}\n\t\tkd := pullDecoderNoAlloc(coders[ccids[0]], coders)\n\t\treturn func(r io.Reader) {\n\t\t\tl, _ := coder.DecodeVarInt(r)\n\t\t\tioutilx.ReadN(r, int(l))\n\t\t\tkd(r)\n\t\t}\n\tcase urns.CoderRow:\n\t\tpanic(fmt.Sprintf(\"Runner forgot to LP this Row Coder. %v\", prototext.Format(c)))\n\tdefault:\n\t\tpanic(fmt.Sprintf(\"unknown coder urn key: %v\", urn))\n\t}\n}\n\n// debugCoder is developer code to get the structure of a proto coder visible when\n// debugging coder errors in prism. It may sometimes be unused, so we do this to avoid\n// linting errors.\nvar _ = debugCoder\n\nfunc debugCoder(cid string, coders map[string]*pipepb.Coder) string {\n\tvar b strings.Builder\n\tb.WriteString(cid)\n\tb.WriteRune('\\n')\n\tc := coders[cid]\n\tif len(c.ComponentCoderIds) > 0 {\n\t\tb.WriteRune('\\t')\n\t\tb.WriteString(strings.Join(c.ComponentCoderIds, \", \"))","sourceCodeStart":364,"sourceCodeEnd":400,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/go/pkg/beam/runners/prism/internal/coders.go#L364-L400","documentation":"Row coders (beam:coders:row:v1) must be length-prefixed (LP) wrapped by the runner before reaching this decoder path. prism panics because it received a raw Row coder it cannot decode — the runner failed to apply the length-prefixing coder transformation.","triggerScenarios":"pullDecoderNoAlloc hits case urns.CoderRow, which is unconditionally a panic: a Row coder survived to decode time without being replaced by an LP-prefixed variant during prism's coder preprocessing.","commonSituations":"A prism bug where coder preprocessing skipped Row coders for some pipeline shapes; custom pipelines injecting raw Row coders directly into the coder registry; newer SDKs introducing Row coder forms prism's preprocessor doesn't recognize.","solutions":["Upgrade prism/Beam to the latest version where Row coder LP handling may be fixed","Check the pipeline for custom coder injection that bypasses prism's preprocessing","Reproduce with a minimal pipeline and report the transform producing the raw Row coder to the Beam project","As a workaround, force a different representation (e.g. wrap elements) so a non-Row coder is used"],"exampleFix":null,"handlingStrategy":"fallback","validationCode":"// detect a raw Row coder before it reaches prism\nif coder.GetUrn() == \"beam:coders:row:v1\" && !isLengthPrefixed(coder) { return errors.New(\"row coder must be LP-wrapped before prism decode\") }","typeGuard":null,"tryCatchPattern":"defer func() { if r := recover(); r != nil { log.Errorf(\"row coder LP invariant broken: %v\", r) } }()","preventionTips":["Upgrade prism/Beam regularly so Row coder LP preprocessing stays current","Avoid injecting raw Row coder protos into the coder registry","Minimalize pipelines when testing new SDK features that change coder output"],"tags":["go","beam","prism","coder","row-coder","panic"],"backgroundTag":"internal-invariant-violation","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"}