risingwavelabs/risingwave · error

invalid value for boolean: {:?}

Error message

invalid value for boolean: {:?}

What it means

Raised in `mysql_datum_to_rw_datum` when a Boolean column's value is fetched as a byte vector (Bit(1) path) but the byte slice is neither exactly `[0]` nor `[1]`. RisingWave only maps those two exact bit patterns to false/true; any other byte sequence (e.g. multi-byte BIT values) is rejected with the offending value in the message.

Source

Thrown at src/connector/src/parser/mysql.rs:136

            // This handles backwards compatibility,
            // before https://github.com/risingwavelabs/risingwave/pull/19071
            // we permit boolean and tinyint(1) to be equivalent to boolean in RW.
            if let Some(Ok(val)) = mysql_row.get_opt::<Option<bool>, _>(mysql_datum_index) {
                return Ok(val.map(ScalarImpl::from));
            }
            // Bit(1)
            match mysql_row.take_opt::<Option<Vec<u8>>, _>(mysql_datum_index) {
                None => bail!(
                    "no value found at column: {}, index: {}",
                    column_name,
                    mysql_datum_index
                ),
                Some(Ok(val)) => match val {
                    None => Ok(None),
                    Some(val) => match val.as_slice() {
                        [0] => Ok(Some(ScalarImpl::from(false))),
                        [1] => Ok(Some(ScalarImpl::from(true))),
                        _ => Err(anyhow!("invalid value for boolean: {:?}", val)),
                    },
                },
                Some(Err(e)) => Err(anyhow::Error::new(e)
                    .context("failed to deserialize MySQL value into rust value")
                    .context(format!(
                        "column: {}, index: {}, rust_type: Vec<u8>",
                        column_name, mysql_datum_index,
                    ))),
            }
        }
        DataType::Int16 => {
            handle_data_type!(mysql_row, mysql_datum_index, column_name, i16)
        }
        DataType::Int32 => {
            handle_data_type!(mysql_row, mysql_datum_index, column_name, i32)
        }
        DataType::Int64 => {
            handle_data_type_with_signed!(mysql_row, mysql_datum_index, column_name, i64, u64)

View on GitHub (pinned to 6469eb736d)

Solutions

  1. Change the MySQL column to BIT(1) or TINYINT(1) if boolean semantics are intended.
  2. Change the RisingWave source column type to a matching type (e.g. BYTEA/VARCHAR) instead of BOOLEAN for BIT(n>1) columns.
  3. Sanitize application writes to only store 0/1 in BIT columns consumed by RisingWave.

Example fix

// before: BIT(8) mapped as BOOLEAN in RW source
flags BIT(8)  -- source column: flags BOOLEAN
// after: widen or remap
-- MySQL: ALTER TABLE t MODIFY flags BIT(1);  or RW: flags BYTEA
Defensive patterns

Strategy: validation

Validate before calling

-- Ensure the column is single-bit before mapping to BOOLEAN:
SELECT CHARACTER_MAXIMUM_LENGTH FROM information_schema.columns
WHERE table_name='t' AND column_name='flags';  -- must be 1 for BIT

Prevention

When it happens

Trigger: Decoding a MySQL `BIT(n)` column with n > 1 (returns multi-byte Vec<u8>) as a RisingWave BOOLEAN; a corrupt or unexpected binary payload in the bool column.

Common situations: Using a MySQL BIT(8)/BIT(n>1) column mapped to BOOLEAN in the CREATE SOURCE statement; upstream application writing values other than b'0'/b'1' into a BIT column.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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