apache/beam · error
buildDescriptor: failed to handle coder on stage
Error message
buildDescriptor: failed to handle coder on stage %v for side input %+v, pcol %q %v: %w
What it means
Side input PCollections must have coders that can be rewritten to concrete portable coders before a stage runs. If lpUnknownCoders fails on the side input's coder ID, prism cannot materialize the side input data and aborts stage construction, reporting the stage, side input, and PCollection proto.
Solutions
- Check the wrapped error for the specific unknown coder URN/ID
- Register or replace the custom coder with a standard (LP-representable) coder
- Verify side input PCollection coders exist in components.coders
- Test with default coders to confirm the coder is the cause
Example fix
// before
si := beam.SideInput{...} // element coder unknown to runner
// after
pc := beam.Create(p, myItems...)
beam.RegisterCoder(reflect.TypeOf(MyType{}), encodeFn, decodeFn) // make coder portable Defensive patterns
Strategy: validation
Validate before calling
// Ensure side input is KV-encodable with known coders before use
if _, ok := comps.GetCoders()[sideInputPcol.GetCoderId()]; !ok {
return fmt.Errorf("side input coder %q unknown", sideInputPcol.GetCoderId())
} Prevention
- Prefer standard coders for side inputs
- Avoid unregistered custom coders in cross-language side inputs
- Verify with a small pipeline that side inputs materialize
When it happens
Trigger: lpUnknownCoders(oCID, coders, comps.GetCoders()) errors while processing a stage's sideInputs — coder referenced by the side input PCollection is unknown or has unresolvable components.
Common situations: Side inputs whose elements use custom coders; cross-language side inputs; malformed component graph after fusion/optimization.
Understand the failure class
Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.
Related errors
- buildDescriptor: couldn't retrieve coder
- buildDescriptor: couldn't rewrite coder
- buildDescriptor: failed to handle coder on stage
- buildDescriptor: failed to handle coder on stage
- Could not decode the default value with the provided coder
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/b7debef788c464d9.
Report an issue: GitHub.
Appendix: source
Thrown at sdks/go/pkg/beam/runners/prism/internal/stage.go:582
col2Coders[o.Global] = engine.PColInfo{
GlobalID: o.Global,
WindowCoder: winCoder,
WDec: wDec,
WEnc: wEnc,
EDec: ed,
KeyDec: kd,
}
transforms[sinkID] = sinkTransform(sinkID, portFor(wOutCid, wk), o.Global)
}
var prepareSides []func(b *worker.B, watermark mtime.Time)
for _, si := range stg.sideInputs {
col := clonePColToBundle(si.Global)
oCID := col.GetCoderId()
nCID, err := lpUnknownCoders(oCID, coders, comps.GetCoders())
if err != nil {
return fmt.Errorf("buildDescriptor: failed to handle coder on stage %v for side input %+v, pcol %q %v:\n%w", stg.ID, si, si.Global, prototext.Format(col), err)
}
if oCID != nCID {
// Add a synthetic PCollection set with the new coder.
newGlobal := si.Global + "_prismside"
pcollections[newGlobal] = &pipepb.PCollection{
DisplayData: col.GetDisplayData(),
UniqueName: col.GetUniqueName(),
CoderId: nCID,
IsBounded: col.GetIsBounded(),
WindowingStrategyId: col.WindowingStrategyId,
}
// Update side inputs to point to new PCollection with any replaced coders.
transforms[si.Transform].GetInputs()[si.Local] = newGlobal
// TODO: replace si.Global with newGlobal?
}
prepSide, err := handleSideInput(si, comps, transforms, pcollections, coders, em)
if err != nil {
slog.Error("buildDescriptor: handleSideInputs", "error", err, slog.String("transformID", si.Transform))View on GitHub (pinned to 12126d8942)