apache/beam · critical

stage[ ] no parent for side input , with parent ID

Error message

stage[%v] no parent for side input %v, with parent ID %v

What it means

After finding the side input's parent stage ID, Prism looks the stage up in em.stages. This panic fires when the parent ID is registered but no stage with that ID exists, meaning the stage table and the pcolParents map are out of sync during side-input readiness evaluation.

Solutions

  1. Retry or rerun the pipeline — if intermittent, it may be a lifecycle race fixed in newer Beam versions
  2. Inspect the pipeline graph to see which transform produces the side input and whether it forms a normal stage
  3. Simplify side-input topology (avoid views over PCollections produced by fused/optimized stages)
  4. Upgrade Apache Beam / prism runner to the latest release and retest
  5. Report with a minimal repro if consistent — this is an internal runner invariant failure
Defensive patterns

Strategy: retry

Try / catch

// Rerun on intermittent lifecycle failures
for attempt := 0; attempt < 3; attempt++ {
    if err := runPipeline(ctx); err == nil { break }
    time.Sleep(time.Second * time.Duration(attempt+1))
}

Prevention

When it happens

Trigger: em.pcolParents[side.Global] returns a valid pID, but em.stages[pID] is absent — stage lifecycle mismatch (parent stage removed/not yet created) when checking whether a side input is ready relative to upstream watermark.

Common situations: Runner-internal race or translation inconsistency; typically seen with cross-language pipelines or unusual graph shapes where parent stages are pruned but side-input references remain.

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


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

Appendix: source

Thrown at sdks/go/pkg/beam/runners/prism/internal/engine/elementmanager.go:2600

		// stages that read one keep waiting.
	case inputW == upstreamW && previousInputW == inputW:
		// Otherwise, use the progression of watermark to determine the bundle readiness.
		slog.Debug("bundleReady: unchanged upstream watermark",
			slog.String("stage", ss.ID),
			slog.Group("watermark",
				slog.Any("upstream == input == previousInput", inputW)))
		return mtime.MinTimestamp, false, ptimeEventsReady, injectedReady
	}

	ready := true
	for _, side := range ss.sides {
		pID, ok := em.pcolParents[side.Global]
		if !ok {
			panic(fmt.Sprintf("stage[%v] no parent ID for side input %v", ss.ID, side))
		}
		parent, ok := em.stages[pID]
		if !ok {
			panic(fmt.Sprintf("stage[%v] no parent for side input %v, with parent ID %v", ss.ID, side, pID))
		}
		ow := parent.OutputWatermark()
		if upstreamW > ow {
			ready = false
		}
	}
	return upstreamW, ready, ptimeEventsReady, injectedReady
}

// processingTimeNow gives the current processing time for the runner.
func (em *ElementManager) processingTimeNow() (ret mtime.Time) {
	if em.testStreamHandler != nil && !em.testStreamHandler.completed {
		return em.testStreamHandler.Now()
	}

	// "Test" mode -> advance to next processing time event if any, to allow execution.
	if !em.config.EnableRTC {
		if t, ok := em.processTimeEvents.Peek(); ok {

View on GitHub (pinned to 12126d8942)