risingwavelabs/risingwave · error · SinkError::BigQuery

bigquery insert error

Error message

bigquery insert error {:?}

What it means

After writing rows through the BigQuery Storage Write API, the AppendRows response is inspected: if it carries per-row errors (append_rows_response.row_errors is non-empty), this error surfaces them. It means BigQuery rejected some or all rows in the batch, e.g. due to schema mismatch or invalid row data.

Solutions

  1. Compare the sink schema with the remote table: query INFORMATION_SCHEMA.COLUMNS and align columns/types.
  2. Drop and recreate the sink (and optionally the table with auto_create=true) so the protobuf schema matches the current table schema.
  3. Inspect row_errors details (index + message) in the log to identify the offending row's field.
  4. Check required-field constraints; adjust source data or make columns nullable.
Defensive patterns

Strategy: validation

Validate before calling

-- Keep the sink schema and remote table schema aligned;
-- verify before creating the sink:
SELECT column_name, data_type
FROM `<project>.<dataset>.INFORMATION_SCHEMA.COLUMNS`
WHERE table_name = '<table>' ORDER BY ordinal_position;

Try / catch

match sink_write_result {
    Err(SinkError::BigQuery(e)) if e.to_string().contains("bigquery insert error") => {
        // parse row_errors from the message, fix schema/data, recreate sink if needed
    }
    other => other?,
}

Prevention

When it happens

Trigger: resp_to_stream processing an append_rows_response whose row_errors vector is non-empty - rows in the submitted protobuf batch failed validation against the BigQuery table schema.

Common situations: Sink schema drifted from the remote BigQuery table (missing/renamed columns, wrong types); NULL values in required fields; table recreated with a different schema than the one validated at sink creation.

Related errors


AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11). Data as JSON: /api/errors/bc45efda6ab8fd91. Report an issue: GitHub.

Appendix: source

Thrown at src/connector/src/sink/big_query.rs:839

            Status,
        >,
    >
    + 'static
    + Send,
) {
    let mut resp_stream = resp_stream
        .await
        .map_err(|e| SinkError::BigQuery(e.into()))?
        .into_inner();
    loop {
        match resp_stream
            .message()
            .await
            .map_err(|e| SinkError::BigQuery(e.into()))?
        {
            Some(append_rows_response) => {
                if !append_rows_response.row_errors.is_empty() {
                    return Err(SinkError::BigQuery(anyhow::anyhow!(
                        "bigquery insert error {:?}",
                        append_rows_response.row_errors
                    )));
                }
                if let Some(google_cloud_googleapis::cloud::bigquery::storage::v1::append_rows_response::Response::Error(status)) = append_rows_response.response{
                            return Err(SinkError::BigQuery(anyhow::anyhow!(
                                "bigquery insert error {:?}",
                                status
                            )));
                        }
                yield ();
            }
            None => {
                return Err(SinkError::BigQuery(anyhow::anyhow!(
                    "bigquery insert error: end of resp stream",
                )));
            }
        }

View on GitHub (pinned to 6469eb736d)