apache/beam · critical

Runner forgot to LP this Row Coder. %v

Error message

Runner forgot to LP this Row Coder. %v

What it means

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.

Source

Thrown at sdks/go/pkg/beam/runners/prism/internal/coders.go:382

		ed := pullDecoderNoAlloc(coders[ccids[0]], coders)
		wd := pullDecoderNoAlloc(coders[ccids[1]], coders)
		return func(r io.Reader) {
			ed(r)
			wd(r)
		}
	case urns.CoderShardedKey:
		ccids := c.GetComponentCoderIds()
		if len(ccids) != 1 {
			panic(fmt.Sprintf("ShardedKey coder must have only 1 component: %s", prototext.Format(c)))
		}
		kd := pullDecoderNoAlloc(coders[ccids[0]], coders)
		return func(r io.Reader) {
			l, _ := coder.DecodeVarInt(r)
			ioutilx.ReadN(r, int(l))
			kd(r)
		}
	case urns.CoderRow:
		panic(fmt.Sprintf("Runner forgot to LP this Row Coder. %v", prototext.Format(c)))
	default:
		panic(fmt.Sprintf("unknown coder urn key: %v", urn))
	}
}

// debugCoder is developer code to get the structure of a proto coder visible when
// debugging coder errors in prism. It may sometimes be unused, so we do this to avoid
// linting errors.
var _ = debugCoder

func debugCoder(cid string, coders map[string]*pipepb.Coder) string {
	var b strings.Builder
	b.WriteString(cid)
	b.WriteRune('\n')
	c := coders[cid]
	if len(c.ComponentCoderIds) > 0 {
		b.WriteRune('\t')
		b.WriteString(strings.Join(c.ComponentCoderIds, ", "))

View on GitHub (pinned to 12126d8942)

Solutions

  1. Upgrade prism/Beam to the latest version where Row coder LP handling may be fixed
  2. Check the pipeline for custom coder injection that bypasses prism's preprocessing
  3. Reproduce with a minimal pipeline and report the transform producing the raw Row coder to the Beam project
  4. As a workaround, force a different representation (e.g. wrap elements) so a non-Row coder is used
Defensive patterns

Strategy: fallback

Validate before calling

// detect a raw Row coder before it reaches prism
if coder.GetUrn() == "beam:coders:row:v1" && !isLengthPrefixed(coder) { return errors.New("row coder must be LP-wrapped before prism decode") }

Try / catch

defer func() { if r := recover(); r != nil { log.Errorf("row coder LP invariant broken: %v", r) } }()

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


AI-assisted analysis of apache/beam@12126d8942 (2026-09-13). Data as JSON: /api/errors/a80a48d410464b90. Report an issue: GitHub.