{"record":{"id":"11a09dbe0282825c","repo":"risingwavelabs/risingwave","slug":"failed-to-deserialize-mysql-value-into-rust-value","errorCode":null,"errorMessage":"failed to deserialize MySQL value into rust value","messagePattern":"failed to deserialize MySQL value into rust value","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/connector/src/parser/mysql.rs","lineNumber":40,"sourceCode":"use thiserror_ext::AsReport;\n\nuse crate::parser::utils::log_error;\n\nstatic LOG_SUPPRESSOR: LazyLock<LogSuppressor> = LazyLock::new(LogSuppressor::default);\nuse anyhow::anyhow;\nuse chrono::NaiveDate;\nuse risingwave_common::bail;\nuse risingwave_common::types::{\n    DataType, Date, Datum, Decimal, JsonbVal, ScalarImpl, Time, Timestamp, Timestamptz,\n};\nuse rust_decimal::Decimal as RustDecimal;\n\nmacro_rules! handle_data_type {\n    ($row:expr, $i:expr, $name:expr, $typ:ty) => {{\n        match $row.take_opt::<Option<$typ>, _>($i) {\n            None => bail!(\"no value found at column: {}, index: {}\", $name, $i),\n            Some(Ok(val)) => Ok(val.map(|v| ScalarImpl::from(v))),\n            Some(Err(e)) => Err(anyhow::Error::new(e.clone())\n                .context(\"failed to deserialize MySQL value into rust value\")\n                .context(format!(\n                    \"column: {}, index: {}, rust_type: {}\",\n                    $name,\n                    $i,\n                    stringify!($typ),\n                ))),\n        }\n    }};\n    ($row:expr, $i:expr, $name:expr, $typ:ty, $rw_type:ty) => {{\n        match $row.take_opt::<Option<$typ>, _>($i) {\n            None => bail!(\"no value found at column: {}, index: {}\", $name, $i),\n            Some(Ok(val)) => Ok(val.map(|v| ScalarImpl::from(<$rw_type>::from(v)))),\n            Some(Err(e)) => Err(anyhow::Error::new(e.clone())\n                .context(\"failed to deserialize MySQL value into rw value\")\n                .context(format!(\n                    \"column: {}, index: {}, rw_type: {}\",\n                    $name,","sourceCodeStart":22,"sourceCodeEnd":58,"githubUrl":"https://github.com/risingwavelabs/risingwave/blob/6469eb736d691e8e9b8a419a57edd6429ca77417/src/connector/src/parser/mysql.rs#L22-L58","documentation":"The `handle_data_type!` macro wraps MySQL client deserialization failures (`Some(Err(e))` from `take_opt`) with the context \"failed to deserialize MySQL value into rust value\" plus column name, index, and the target Rust type. This means the raw MySQL value could not be converted into the requested Rust type (e.g. malformed string for a numeric type, incompatible wire format).","triggerScenarios":"`row.take_opt::<Option<T>, _>(i)` returns Err for column `$i` — the on-wire MySQL value's type does not match the Rust type parameter `$typ` the macro was instantiated with.","commonSituations":"Schema drift: column type changed upstream (e.g. INT to VARCHAR) so the typed read fails; charset/encoding issues on string columns read as numeric; connector type mapping table out of sync with the MySQL server version.","solutions":["Read the inner error and context (column, index, rust_type) to identify the offending column and verify its actual MySQL type.","Update the source table or RW schema so the declared type matches the upstream column type, then re-create/restart the source.","If it is data corruption in a specific row, repair or skip the row (e.g. fix the value upstream and resume the snapshot)."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"match decode_col(row, idx, name) {\n    Err(e) if e.to_string().contains(\"failed to deserialize MySQL value into rust value\") => {\n        tracing::error!(\"mysql type mismatch: {e:#}\"); // {:#} prints the full context chain\n        quarantine_row(row_id);\n    }\n    other => other?,\n}","preventionTips":["Keep the RW-to-MySQL type mapping in sync with upstream DDL changes.","Use DESCRIBE/INFORMATION_SCHEMA checks against the live table before starting CDC.","Alert on any deserialization error; it usually means schema drift or data corruption."],"tags":["mysql","cdc","deserialization","type-mismatch"],"backgroundTag":"type-mismatch","analyzedSha":"6469eb736d691e8e9b8a419a57edd6429ca77417","analyzedAt":"2026-09-11T21:06:21.487Z","contentChangedAt":"2026-09-11T21:06:21.487Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}