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.

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.

Appendix: 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)