risingwavelabs/risingwave · error

Can't convert int {} to ScalarImpl::{}

Error message

Can't convert int {} to ScalarImpl::{}

What it means

`to_int_scalar` converts a Postgres integer read as i64 into a RisingWave `ScalarImpl` matching the declared column type. If the declared `DataType` is not Int16/Int32/Int64 the function panics with this message rather than returning an error. It indicates an internal mismatch between the type recorded in schema metadata and the actual key column type.

Source

Thrown at src/connector/src/source/cdc/external/postgres.rs:833

            }
            left = right;
            right = left.map(|l| l.saturating_add(saturated_split_max_size));
        }
    }

    fn split_column(&self, options: &CdcTableSnapshotSplitOption) -> Field {
        self.rw_schema.fields[self.pk_indices[options.backfill_split_pk_column_index as usize]]
            .clone()
    }
}

fn to_int_scalar(i: i64, data_type: &DataType) -> ScalarImpl {
    match data_type {
        DataType::Int16 => ScalarImpl::Int16(i.try_into().unwrap()),
        DataType::Int32 => ScalarImpl::Int32(i.try_into().unwrap()),
        DataType::Int64 => ScalarImpl::Int64(i),
        _ => {
            panic!("Can't convert int {} to ScalarImpl::{}", i, data_type)
        }
    }
}

fn try_increase_split_id(split_id: &mut i64) -> ConnectorResult<()> {
    match split_id.checked_add(1) {
        Some(s) => {
            *split_id = s;
            Ok(())
        }
        None => Err(anyhow::anyhow!("too many CDC snapshot splits").into()),
    }
}

/// Use the first column of primary keys to split table.
fn is_supported_even_split_data_type(data_type: &DataType) -> bool {
    matches!(
        data_type,

View on GitHub (pinned to 6469eb736d)

Solutions

  1. Report/fix the type mapping so only integer PK types take the integer-scalar path.
  2. Refresh the CDC table schema (re-create the table) so metadata matches the upstream types.
  3. Verify the split PK column is actually a smallint/integer/bigint upstream.
  4. If you maintain the code, convert this panic into a `ConnectorError` for graceful handling.

Example fix

// before (panic on mismatch)
_ => panic!("Can't convert int {} to ScalarImpl::{}", i, data_type),
// after (graceful error)
_ => return Err(ConnectorError::from(anyhow::anyhow!(
    "Can't convert int {} to ScalarImpl::{}", i, data_type))),
Defensive patterns

Strategy: type-guard

Validate before calling

// Only take the integer path when the mapped type is a signed integer
if !matches!(data_type, DataType::Int16 | DataType::Int32 | DataType::Int64) {
    return Err("split column is not an integer type");
}

Type guard

fn is_supported_int_type(dt: &DataType) -> bool {
    matches!(dt, DataType::Int16 | DataType::Int32 | DataType::Int64)
}

Try / catch

// The function panics, so guard callsites instead:
if !is_supported_int_type(&pk_data_type) {
    return Err(anyhow::anyhow!("integer split path not applicable to {}", pk_data_type).into());
}
let scalar = to_int_scalar(i, &pk_data_type);

Prevention

When it happens

Trigger: `snapshot_read_inner` calls `to_int_scalar` for a split's PK boundary value whose `DataType` is anything other than Int16, Int32, or Int64 (e.g. UInt types, Decimal) — i.e. the split column was treated as an integer type but its metadata type differs.

Common situations: Schema drift changing a PK column type after splits were planned; metadata/type mapping bugs in `pg_type_to_rw_type`; using an uneven-split path on a column whose mapped type is not a signed integer.

Understand the failure class

Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.

Related errors


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