apache/beam · error · Error
Cannot be called outside of a DoFn's process method.
Error message
Cannot be called outside of a DoFn's process method.
What it means
ParDoLookupParam.lookup() requires a side-input provider that is only injected while a DoFn's process method runs. If provider is undefined — meaning lookup() was called outside element processing — it throws 'Cannot be called outside of a DoFn's process method.'
Source
Thrown at sdks/typescript/src/apache_beam/transforms/pardo.ts:311
*/
export class ParDoParam {
// Provided externally.
/** @internal */
protected provider: ParamProvider | undefined;
/** @internal */
constructor(readonly parDoParamName: string) {}
}
/**
* At runtime, one can invoke the special `lookup` method to retrieve the
* relevant value associated with the currently-being-processed element.
*/
export class ParDoLookupParam<T> extends ParDoParam {
// TODO: Nameing "get" seems to be special.
lookup(): T {
if (this.provider === undefined) {
throw new Error("Cannot be called outside of a DoFn's process method.");
}
return this.provider.lookup(this);
}
}
/**
* At runtime, one can invoke the special `update` method to update the
* relevant value associated with the currently-being-processed element.
*/
export class ParDoUpdateParam<T> extends ParDoParam {
update(value: T): void {
if (this.provider === undefined) {
throw new Error("Cannot be called outside of a DoFn's process method.");
}
this.provider.update(this, value);
}View on GitHub (pinned to 12126d8942)
Solutions
- Move the lookup() call inside the DoFn's processElement/process method where the provider is bound.
- For tests, construct a ParDoLookupParam with a mock provider set instead of relying on runtime injection.
- Use startBundle/process-scoped state to store values you need outside process.
Example fix
// before
class MyFn extends DoFn {
setup() { this.value = this.sideInput.lookup(); } // throws
}
// after
class MyFn extends DoFn {
processElement(e) { const v = this.sideInput.lookup(); ... }
} Defensive patterns
Strategy: validation
Validate before calling
function canLookup(param: ParDoLookupParam<T>) { return param.provider !== undefined; }
if (!canLookup(sideInput)) console.warn("lookup() only valid inside processElement"); Type guard
function inProcessContext<T>(p: ParDoLookupParam<T>): p is ParDoLookupParam<T> & { provider: NonNullable<ParDoLookupParam<T>["provider"]> } {
return p.provider !== undefined;
} Try / catch
try {
const v = this.sideInput.lookup();
} catch (e) {
if (e.message.includes("outside of a DoFn's process method")) {
throw new Error("Move side-input lookup into processElement");
} else throw e;
} Prevention
- Only call side-input lookup/update inside processElement
- Never call side-input APIs from setup/teardown/startBundle/finishBundle
- Inject mock providers in unit tests
When it happens
Trigger: Calling sideInput.lookup() (a ParDoLookupParam captured in the DoFn) from setup/teardown/startBundle/finishBundle, from the constructor, or from plain application code outside the pipeline.
Common situations: Developers caching the side-input object and calling lookup() at class level or in unit tests without executing through the DoFn process pipeline context.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- SideInput unsupported in ${context}
- calling getSideInput() with unknown view
- Attempting to emit an element outside of a @ProcessElement c
- Cannot access sideInput in non-window observing context.
- Cannot access StartBundleContext outside of @StartBundle met
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/d4db585005df3820.
Report an issue: GitHub.