apache/beam · error

Missing output value in method

Error message

Missing output value in method %v, %v method should return %v when %v method is defined.

What it means

When a splittable DoFn defines TruncateRestriction, its ProcessElement must return a sdf.ProcessContinuation as one of its outputs. Beam raises this error if TruncateRestriction exists but ProcessElement has no ProcessContinuation return value, because truncation only makes sense for resumable processing.

Solutions

  1. Change ProcessElement to return (your outputs, sdf.ProcessContinuation) and use sdf.ResumeProcessElement or sdf.StopProcessing as appropriate.
  2. If you do not need resumable processing, remove the TruncateRestriction method entirely.
  3. Use beam.Validate/DoFn validation locally by writing a unit test constructing the DoFn with beam.TryCreateDoFn to catch this before pipeline runs.

Example fix

// before
func (fn *f) ProcessElement(rt *sdf.LockRTracker, r rangeT, emit func(int)) {}
// after
func (fn *f) ProcessElement(rt *sdf.LockRTracker, r rangeT, emit func(int)) sdf.ProcessContinuation {
    ...
    return sdf.ResumeProcessElement()
}
Defensive patterns

Strategy: validation

Validate before calling

func hasProcessContinuation(fn interface{}) bool {
    t := reflect.TypeOf(fn)
    pe, ok := t.MethodByName("ProcessElement")
    if !ok { return false }
    pc := reflect.TypeOf((*sdf.ProcessContinuation)(nil)).Elem()
    for i := 0; i < pe.Type.NumOut(); i++ {
        if pe.Type.Out(i) == pc { return true }
    }
    return false
}
// require: hasProcessContinuation(dofn) || !hasTruncateRestriction(dofn)

Type guard

func truncateNeedsContinuation(fn interface{}) bool {
    _, hasTrunc := reflect.TypeOf(fn).MethodByName("TruncateRestriction")
    return hasTrunc && !hasProcessContinuation(fn) // must be false before submission
}

Prevention

When it happens

Trigger: Adding a TruncateRestriction method to an SDF whose ProcessElement returns only element outputs (no sdf.ProcessContinuation), then running a pipeline where a splittable element gets truncated (e.g. on drain/failover).

Common situations: Retrofitting an existing SDF with truncation support; copying TruncateRestriction from another DoFn without updating ProcessElement's signature.

Related errors


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

Appendix: source

Thrown at sdks/go/pkg/beam/core/graph/fn.go:1109

			if method.Param[startIdx].T != rTrackerImplT {
				err := errors.Errorf("mismatched restriction tracker type in method %v, param %v. got: %v, want: %v",
					truncateRestrictionName, startIdx, method.Param[startIdx].T, rTrackerImplT)
				return errors.SetTopLevelMsgf(err, "Mismatched restriction tracker type in method %v, "+
					"parameter at index %v. Got: %v, Want: %v (from method %v). "+
					"Ensure that restriction tracker is the first parameter.",
					truncateRestrictionName, startIdx, method.Param[startIdx].T, rTrackerImplT, createTrackerName)
			}
			if method.Ret[0].T != restrictionT {
				err := errors.Errorf("invalid output type in method %v, return %v. got: %v, want: %v",
					truncateRestrictionName, 0, method.Ret[0].T, restrictionT)
				return errors.SetTopLevelMsgf(err, "Invalid output type in method %v, "+
					"return value at index %v. Got: %v, Want: %v (from method %v). "+
					"Ensure that all restrictions in an SDF are the same type.",
					truncateRestrictionName, 0, method.Ret[0].T, restrictionT, createInitialRestrictionName)
			}
			processFn := fn.methods[processElementName]
			if _, exists := processFn.ProcessContinuation(); !exists {
				err := errors.Errorf("missing return value in %v: return value of type %v is not present",
					processElementName, reflect.TypeOf((*sdf.ProcessContinuation)(nil)).Elem())
				return errors.SetTopLevelMsgf(err, "Missing output value in method %v, "+
					"%v method should return %v when %v method is defined.",
					processElementName, processElementName, reflect.TypeOf((*sdf.ProcessContinuation)(nil)).Elem(), truncateRestrictionName)
			}
		}
	}

	return nil
}

func sdfRequiredParamStartIndex(method *funcx.Fn) int {
	if ctxIndex, ok := method.Context(); ok {
		return ctxIndex + 1
	}

	return 0
}

View on GitHub (pinned to 12126d8942)