apache/beam · error · Error

Job finished in state

Error message

Job finished in state ${jobApi.JobState_Enum[finalState]}

What it means

reallyRunPipelines() submits all merged pipelines via the universal runner and awaits waitUntilFinish(); if the final state is not DONE it throws 'Job finished in state <STATE>'. Like Runner.run, it signals the batch of pipelines ended in a failed/cancelled/unknown state rather than completing successfully.

Solutions

  1. Check job/service logs to find which pipeline or step caused the non-DONE state.
  2. Fix the failing pipeline logic, then re-run the multi-pipeline batch.
  3. Catch the error and inspect the state value to decide whether to retry.

Example fix

// before
await multiRunner.runAsync();
// after
try { await multiRunner.runAsync(); }
catch (e) { if (e.message.includes("Job finished in state")) console.error(e.message); throw e; }
Defensive patterns

Strategy: try-catch

Validate before calling

// Ensure all merged pipelines are valid before reallyRunPipelines
for (const p of allPipelines) validatePipelineComponents(p);

Type guard

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

Try / catch

try {
  await multiRunner.runAsync();
} catch (e) {
  if (e.message.startsWith("Job finished in state")) {
    console.error("Multi-pipeline batch failed:", e.message);
  } else throw e;
}

Prevention

When it happens

Trigger: Calling runAsync()/reallyRunPipelines() on MultiPipelineRunner when the underlying submitted job terminates in any JobState_Enum other than DONE.

Common situations: One of the merged test pipelines fails at runtime on the service, the job is cancelled, or infrastructure errors abort the job.

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/04452df02c6858ba. Report an issue: GitHub.

Appendix: source

Thrown at sdks/typescript/src/apache_beam/testing/multi_pipeline_runner.ts:116

      throw new Error("Per-pipeline options not supported.");
    }
    this.mergePipeline(pipeline);
    return new FakePipelineResult();
  }

  async reallyRunPipelines() {
    if (this.allPipelines === undefined) {
      return new FakePipelineResult();
    }
    console.log(this.allPipelines);
    const pipelineResult = await this.underlying.runPipeline(
      this.allPipelines,
      this.options,
    );
    const finalState = await pipelineResult.waitUntilFinish();
    if (finalState != jobApi.JobState_Enum.DONE) {
      // TODO: Grab the last/most severe error message?
      throw new Error(
        "Job finished in state " + jobApi.JobState_Enum[finalState],
      );
    }
    this.allPipelines = undefined;
    return pipelineResult;
  }

  getPrefix(): string {
    try {
      return "namespace_" + this.counter + "_";
    } finally {
      this.counter += 1;
    }
  }

  mergePipeline(pipeline: runnerApi.Pipeline) {
    if (this.allPipelines === undefined) {
      this.allPipelines = runnerApi.Pipeline.create({

View on GitHub (pinned to 12126d8942)