risingwavelabs/risingwave · error

Fast insert failed: {}

Error message

Fast insert failed: {}

What it means

The webhook handler sent a fast-insert request to the compute node and the response status was not Succeeded. The compute node's error_message is embedded in the returned error with HTTP 500. It means the batched fast path for writing webhook payload rows into the table failed on the compute side.

Source

Thrown at src/frontend/src/webhook/mod.rs:178

            }
        };

        let fast_insert_request = FastInsertRequest {
            table_id,
            table_version_id,
            data_chunk: Some(data_chunk.to_protobuf()),
            row_id_index,
            request_id,
            wait_for_persistence: webhook_source_info.wait_for_persistence,
        };
        // execute on the compute node
        let res = execute(fast_insert_request, compute_client).await?;

        if res.status == fast_insert_response::Status::Succeeded as i32 {
            Ok(())
        } else {
            Err(err(
                anyhow!("Fast insert failed: {}", res.error_message),
                StatusCode::INTERNAL_SERVER_ERROR,
            ))
        }
    }

    fn generate_data_chunk(is_batched: bool, body: &Bytes) -> Result<DataChunk> {
        let mut builder = JsonbArrayBuilder::with_type(1, DataType::Jsonb);

        if !is_batched {
            // Use builder to obtain a single column & single row DataChunk
            let json_value = Value::from_text(body).map_err(|e| {
                err(
                    anyhow!(e).context("failed to parse request body"),
                    StatusCode::UNPROCESSABLE_ENTITY,
                )
            })?;

            let jsonb_val = JsonbVal::from(json_value);

View on GitHub (pinned to 6469eb736d)

Solutions

  1. Inspect the embedded res.error_message in the error/response body for the root cause.
  2. Verify the webhook payload matches the table's expected JSON schema (column names/types).
  3. Check compute node health/logs (risingwave compute) and retry the POST.
  4. Confirm the table's webhook source is healthy: SELECT * FROM rw_catalog.rw_webhook_source_info (or equivalent) and re-create the webhook source if corrupted.

Example fix

// before
// compute rejects rows: wrong column type
POST /webhook/table/orders {"amount": "not-a-number"}

// after
POST /webhook/table/orders {"amount": 42}
Defensive patterns

Strategy: try-catch

Validate before calling

// validate payload against the table schema before POST
const required = ['id', 'amount'];
if (!required.every(k => k in payload) || typeof payload.amount !== 'number') {
  throw new Error('payload does not match table schema');
}

Type guard

function isValidWebhookPayload(p: unknown): p is Record<string, string|number|boolean|null> {
  return typeof p === 'object' && p !== null && !Array.isArray(p);
}

Try / catch

try {
  await postWebhook('/table/orders', payload);
} catch (e) {
  if (e.status === 500 && /Fast insert failed/.test(e.message)) {
    logComputeError(e.message); // includes res.error_message
    await retryWithBackoff(() => postWebhook('/table/orders', payload));
  } else { throw e; }
}

Prevention

When it happens

Trigger: POSTing to a webhook endpoint /table where handle_post_request executes the fast insert and res.status != Succeeded: compute node unreachable/overloaded, schema mismatch between payload columns and table, or serialization failure inside the compute node.

Common situations: Webhook payloads whose extracted columns don't match the table schema; compute node crash/restart under load; MV built over the webhook source rejecting rows; network partition between frontend and compute.

Understand the failure class

Background: "API error: {status}" and "HTTP 401/403/404/429/5xx" errors: non-2xx HTTP responses explained — this error's family across 27 libraries.

Related errors


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