{"record":{"id":"99a9d2589d284f60","repo":"risingwavelabs/risingwave","slug":"underlying-lancedb-error","errorCode":null,"errorMessage":"(underlying lancedb::Error)","messagePattern":"\\(underlying lancedb::Error\\)","errorType":"exception","errorClass":"SinkError::LanceDb","httpStatus":null,"severity":"error","filePath":"src/connector/src/sink/lancedb.rs","lineNumber":821,"sourceCode":"            (\n                RW_SINK_ID_TRANSACTION_PROPERTY.to_owned(),\n                self.sink_id.clone(),\n            ),\n            (\n                RW_EPOCH_TRANSACTION_PROPERTY.to_owned(),\n                self.epoch.to_string(),\n            ),\n        ])\n    }\n}\n\n// ---------------------------------------------------------------------------\n// Error conversion\n// ---------------------------------------------------------------------------\n\nimpl From<lancedb::Error> for SinkError {\n    fn from(value: lancedb::Error) -> Self {\n        SinkError::LanceDb(anyhow!(value))\n    }\n}\n\n// ---------------------------------------------------------------------------\n// Tests\n// ---------------------------------------------------------------------------\n\n#[cfg(all(test, not(madsim)))]\nmod tests {\n    use risingwave_common::array::{Array, I32Array, Op, StreamChunk, Utf8Array};\n    use risingwave_common::catalog::{ColumnDesc, ColumnId, Field, Schema};\n    use risingwave_common::id::SinkId;\n    use risingwave_common::types::DataType;\n\n    use super::*;\n    use crate::sink::catalog::SinkType;\n    use crate::sink::writer::SinkWriter;\n    use crate::sink::{SinglePhaseCommitCoordinator, TwoPhaseCommitCoordinator};","sourceCodeStart":803,"sourceCodeEnd":839,"githubUrl":"https://github.com/risingwavelabs/risingwave/blob/6469eb736d691e8e9b8a419a57edd6429ca77417/src/connector/src/sink/lancedb.rs#L803-L839","documentation":"A blanket `From<lancedb::Error> for SinkError` conversion: every error returned by the LanceDB Rust SDK (connection failures, table-not-found, IO errors, etc.) is wrapped with anyhow and re-raised as SinkError::LanceDb. The message you see is whatever lancedb::Error carried, so the real cause must be read from the wrapped source chain.","triggerScenarios":"Any `?` on a lancedb SDK call across the sink (open table, append rows, commit), e.g. table creation failing due to a bad URI, network errors to the LanceDB service, or storage-credential problems.","commonSituations":"Wrong LanceDB URI in sink options, missing credentials for object-store-backed LanceDB, network/firewall issues between RisingWave and the LanceDB service, table deleted externally.","solutions":["Inspect the anyhow source chain (log with {:#} or {:?}) to find the underlying lancedb::Error cause","Verify sink options: URI, table name, and credentials are correct and reachable from the RisingWave node","Check network connectivity to the LanceDB endpoint (and S3/GCS if object-store backed) and retry transient failures","Confirm the target table exists and was not dropped or locked by another process"],"exampleFix":"// before\n// error surfaced only as: LanceDB sink error: <short message>\n// after\ntracing::error!(\"lancedb sink error: {e:#}\"); // full source chain shows root cause","handlingStrategy":"try-catch","validationCode":"// pre-flight: verify the LanceDB endpoint and table are reachable\nasync fn table_openable(uri: &str, table: &str) -> bool {\n    lancedb::connect(uri)\n        .unwrap()\n        .open_table(table)\n        .await\n        .is_ok()\n}","typeGuard":"fn underlying_lancedb_error(err: &SinkError) -> Option<&anyhow::Error> {\n    match err { SinkError::LanceDb(e) => Some(e), _ => None }\n}","tryCatchPattern":"match write_result {\n    Err(SinkError::LanceDb(e)) => {\n        tracing::error!(\"lancedb op failed: {e:#}\"); // full anyhow source chain\n        // branch on cause: retry transient network errors, fail on config errors\n    }\n    other => other,\n}","preventionTips":["Validate the sink URI/table name/credentials before creating the sink","Monitor network reachability between RisingWave nodes and the LanceDB endpoint","Never drop the LanceDB table while its sink is active","Log wrapped errors with {:#} so the root lancedb::Error is visible"],"tags":["lancedb","sink","error-conversion","sdk"],"backgroundTag":"database-write-failed","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"}