{"record":{"id":"12d966f89e3f72c8","repo":"risingwavelabs/risingwave","slug":"no-value-found-at-column-index","errorCode":null,"errorMessage":"no value found at column: {}, index: {}","messagePattern":"no value found at column: (.+?), index: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/connector/src/parser/mysql.rs","lineNumber":38,"sourceCode":"use risingwave_common::log::LogSuppressor;\nuse risingwave_common::row::OwnedRow;\nuse 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!(","sourceCodeStart":20,"sourceCodeEnd":56,"githubUrl":"https://github.com/risingwavelabs/risingwave/blob/6469eb736d691e8e9b8a419a57edd6429ca77417/src/connector/src/parser/mysql.rs#L20-L56","documentation":"Inside the `handle_data_type!` macro (first arm, direct Rust-type conversion), `row.take_opt` returned `None`, meaning the MySQL row has no value slot at the requested column index. The macro converts this absence into an anyhow error identifying the column name and index. Note: the DECLARED/USED metadata pointing at ci/scripts Python files is unrelated noise; the actual throw site is this Rust macro in src/connector/src/parser/mysql.rs.","triggerScenarios":"The macro is invoked with a column index `$i` that exceeds the number of columns in the fetched MySQL row, i.e. schema/metadata column list is wider than the actual row returned by the MySQL client.","commonSituations":"MySQL CDC snapshot where the table was altered between metadata fetch and row read (column count mismatch); mismatch between the declared RW column list and the binlog/row event column set; replication protocol desync after schema change.","solutions":["Re-fetch the table schema so column metadata matches the current MySQL table, then retry the snapshot.","Verify the index passed to the macro comes from iterating the same column list used to read the row.","Check for concurrent ALTER TABLE on the source during snapshot; pause DDL or re-create the source."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"assert!(idx < row.as_ref().columns().len(), \"column index {} out of range for MySQL row ({} cols)\", idx, row.as_ref().columns().len());","typeGuard":null,"tryCatchPattern":"match decode_col(row, idx, name) {\n    Err(e) if e.to_string().contains(\"no value found at column\") => handle_schema_drift(),\n    other => other,\n}","preventionTips":["Keep the column metadata list and the row read loop derived from the same schema object.","Freeze DDL on the MySQL source during snapshot/backfill.","Log row width vs expected column count once per batch to catch drift early."],"tags":["mysql","cdc","column-index","schema-drift"],"backgroundTag":"index-out-of-bounds","analyzedSha":"6469eb736d691e8e9b8a419a57edd6429ca77417","analyzedAt":"2026-09-11T21:06:21.487Z","contentChangedAt":"2026-09-11T21:06:21.487Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}