apache/beam · error · Error

Job finished in state

Error message

Job finished in state ${JobState_Enum[finalState]}

What it means

Runner.run() awaits runAsync() then waitUntilFinish(); if the job terminates in any state other than DONE (e.g. FAILED, CANCELLED, UNKNOWN), it throws 'Job finished in state <STATE>'. The message names the JobState_Enum numeric value's key so developers can see which terminal state the job reached. It indicates the pipeline ran but did not complete successfully.

Solutions

  1. Inspect job logs on the runner service to find the root cause of the non-DONE state.
  2. Catch the error and check the returned PipelineResult/job state for retryable outcomes before re-submitting.
  3. Fix the pipeline error (bad input, OOM, missing resources) that caused the job to fail.

Example fix

// before
await runner.run(pipeline, options);
// after
try {
  await runner.run(pipeline, options);
} catch (e) {
  console.error("Pipeline did not finish in DONE state:", e.message);
  throw e;
}
Defensive patterns

Strategy: try-catch

Validate before calling

// Validate pipeline options (project, region, tempLocation) before submitting
class MyFn extends DoFn {}
await runner.runAsync(pipeline, options); // prefer runAsync + explicit waitUntilFinish for state control

Type guard

function isDone(state: JobState_Enum) { return state === JobState_Enum.DONE; }

Try / catch

try {
  await runner.run(pipeline, options);
} catch (e) {
  if (e.message.startsWith("Job finished in state")) {
    console.error("Pipeline job failed:", e.message);
    // inspect service logs before retrying
  } else throw e;
}

Prevention

When it happens

Trigger: Calling runner.run(pipeline, options) when the submitted job ends in a non-DONE state — e.g. the job fails on the remote service, is cancelled, or times out.

Common situations: Worker crashes on a Dataflow/Flink job, bad pipeline logic causing runtime failure, job cancelled by a user or platform policy, quota or infrastructure failures.

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


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

Appendix: source

Thrown at sdks/typescript/src/apache_beam/runners/runner.ts:110

export abstract class Runner {
  /**
   * Runs the transform.
   *
   * Resolves to an instance of PipelineResult when the pipeline completes.
   * Use runAsync() to execute the pipeline in the background.
   *
   * @param pipeline
   * @returns A PipelineResult
   */
  async run(
    pipeline: (root: Root) => PValue<any> | Promise<PValue<any>>,
    options?: PipelineOptions,
  ): Promise<PipelineResult> {
    const pipelineResult = await this.runAsync(pipeline, options);
    const finalState = await pipelineResult.waitUntilFinish();
    if (finalState != JobState_Enum.DONE) {
      // TODO: Grab the last/most severe error message?
      throw new Error("Job finished in state " + JobState_Enum[finalState]);
    }
    return pipelineResult;
  }

  /**
   * runAsync() is the asynchronous version of run(), does not wait until
   * pipeline finishes. Use the returned PipelineResult to query job
   * status.
   */
  async runAsync(
    pipeline: (root: Root) => PValue<any> | Promise<PValue<any>>,
    options?: PipelineOptions,
  ): Promise<PipelineResult> {
    const p = new Pipeline();
    await pipeline(new Root(p));
    return this.runPipeline(p.getProto());
  }

View on GitHub (pinned to 12126d8942)