apache/beam · error · IllegalStateException

Retrieving successful inserts is only supported for…

Error message

Retrieving successful inserts is only supported for streaming inserts. Make sure withSuccessfulInsertsPropagation is correctly configured for BigQueryIO.Write object.

What it means

WriteResult.getSuccessfulInserts returns the PCollection of TableRows successfully inserted via the BigQuery streaming insert API. That collection only exists when the write was configured with withSuccessfulInsertsPropagation(); for batch loads or when propagation isn't enabled, it is null and the method throws this IllegalStateException.

Solutions

  1. Add .withSuccessfulInsertsPropagation() to your BigQueryIO.Write transform and use streaming inserts (withMethod(Write.Method.STREAMING_INSERTS)).
  2. If you switched to batch loads, stop calling getSuccessfulInserts — batch loads don't produce per-row insert results; handle job-level errors instead.
  3. Guard the call: only read successful inserts when your write method is STREAMING_INSERTS and the flag was set.

Example fix

// before
WriteResult result = table.apply("write", BigQueryIO.writeTableRows().to(spec).withTemplateCompatibility());
PCollection<TableRow> ok = result.getSuccessfulInserts(); // throws
// after
WriteResult result = table.apply("write", BigQueryIO.writeTableRows().to(spec)
    .withMethod(Write.Method.STREAMING_INSERTS)
    .withSuccessfulInsertsPropagation());
PCollection<TableRow> ok = result.getSuccessfulInserts();
Defensive patterns

Strategy: validation

Validate before calling

if (writeMethod == Write.Method.STREAMING_INSERTS && insertPropagationEnabled) {
  PCollection<TableRow> ok = result.getSuccessfulInserts();
}

Try / catch

try { return result.getSuccessfulInserts(); } catch (IllegalStateException e) { log.warn("No successful-inserts collection; batch write?", e); return null; }

Prevention

When it happens

Trigger: Calling writeResult.getSuccessfulInserts() after a BigQueryIO.Write that was built without .withSuccessfulInsertsPropagation(), or on a batch (FILE_LOADS / STORAGE_API_WRITES) write.

Common situations: Developers switch from streaming inserts to batch loads and keep the getSuccessfulInserts call; forgetting the flag when constructing the Write transform; copying example code that assumed streaming inserts.

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

Appendix: source

Thrown at sdks/java/io/google-cloud-platform/src/main/java/org/apache/beam/sdk/io/gcp/bigquery/WriteResult.java:165

   */
  public PCollection<TableDestination> getSuccessfulTableLoads() {
    Preconditions.checkArgumentNotNull(
        successfulBatchInsertsTag,
        "Cannot use getSuccessfulTableLoads because this WriteResult was not "
            + "configured to produce them.  Note: only batch loads produce successfulTableLoads.");
    return Preconditions.checkArgumentNotNull(
        successfulBatchInserts,
        "Cannot use getSuccessfulTableLoads because this WriteResult was not "
            + "configured to produce them.  Note: only batch loads produce successfulTableLoads.");
  }

  /**
   * Returns a {@link PCollection} containing the {@link TableRow}s that were written to BQ via the
   * streaming insert API.
   */
  public PCollection<TableRow> getSuccessfulInserts() {
    if (successfulInserts == null) {
      throw new IllegalStateException(
          "Retrieving successful inserts is only supported for streaming inserts. "
              + "Make sure withSuccessfulInsertsPropagation is correctly configured for "
              + "BigQueryIO.Write object.");
    }
    return successfulInserts;
  }

  /**
   * Returns a {@link PCollection} containing the {@link TableRow}s that didn't make it to BQ.
   *
   * <p>Only use this method if you haven't enabled {@link
   * BigQueryIO.Write#withExtendedErrorInfo()}. Otherwise use {@link
   * WriteResult#getFailedInsertsWithErr()}
   */
  public PCollection<TableRow> getFailedInserts() {
    Preconditions.checkArgumentNotNull(
        failedInsertsTag,
        "Cannot use getFailedInserts as this WriteResult uses extended errors"

View on GitHub (pinned to 12126d8942)