{"record":{"id":"49fbd0e41cd5875a","repo":"risingwavelabs/risingwave","slug":"can-t-create-deltalake-sink-write-result-from-empt","errorCode":null,"errorMessage":"Can't create deltalake sink write result from empty data!","messagePattern":"Can't create deltalake sink write result from empty data!","errorType":"exception","errorClass":"SinkError","httpStatus":null,"severity":"error","filePath":"src/connector/src/sink/deltalake.rs","lineNumber":782,"sourceCode":"    type Error = SinkError;\n\n    fn try_from(value: &'a DeltaLakeWriteResult) -> std::result::Result<Self, Self::Error> {\n        let metadata =\n            serde_json::to_vec(&value.adds).context(\"cannot serialize deltalake sink metadata\")?;\n        Ok(SinkMetadata {\n            metadata: Some(Serialized(SerializedMetadata { metadata })),\n        })\n    }\n}\n\nimpl DeltaLakeWriteResult {\n    fn try_from(value: &SinkMetadata) -> Result<Self> {\n        if let Some(Serialized(v)) = &value.metadata {\n            let adds = serde_json::from_slice::<Vec<Add>>(&v.metadata)\n                .context(\"Can't deserialize deltalake sink metadata\")?;\n            Ok(DeltaLakeWriteResult { adds })\n        } else {\n            bail!(\"Can't create deltalake sink write result from empty data!\")\n        }\n    }\n}\n\nimpl From<::deltalake::DeltaTableError> for SinkError {\n    fn from(value: ::deltalake::DeltaTableError) -> Self {\n        SinkError::DeltaLake(anyhow!(value))\n    }\n}\n\n#[cfg(all(test, not(madsim)))]\nmod tests {\n    use deltalake::kernel::DataType as SchemaDataType;\n    use deltalake::operations::create::CreateBuilder;\n    use maplit::btreemap;\n    use risingwave_common::array::{Array, I32Array, Op, StreamChunk, Utf8Array};\n    use risingwave_common::catalog::{Field, Schema};\n    use risingwave_common::types::DataType;","sourceCodeStart":764,"sourceCodeEnd":800,"githubUrl":"https://github.com/risingwavelabs/risingwave/blob/6469eb736d691e8e9b8a419a57edd6429ca77417/src/connector/src/sink/deltalake.rs#L764-L800","documentation":"DeltaLakeSinkMetadata is converted into a DeltaLakeWriteResult only when its `metadata` field contains a Some(Serialized(v)) payload; this error is thrown when that payload is absent. It means the sink metadata committed to the meta service carries no serialized delta-lake `Add` actions, so no write result can be reconstructed for commit.","triggerScenarios":"Calling `DeltaLakeWriteResult::try_from(&SinkMetadata)` with a SinkMetadata whose `metadata` field is None (or not the Serialized variant), e.g. after a sink commit that never recorded serialized adds.","commonSituations":"Internal RisingWave sink-commit flows where the DeltaLake sink writer failed to serialize its added files before flush/commit; restoring or replaying metadata that predates serialization; bugs in the sink's `serialize` implementation.","solutions":["Ensure the DeltaLake sink writer's `serialize`/`begin_epoch` path always stores `Metadata::Serialized` with the JSON-encoded Vec<Add> before commit.","Check that no code path replaces or drops the metadata payload (e.g. an empty flush overwriting it with None).","If this occurs on a sink that wrote no data, treat empty commits specially and skip the try_from conversion.","Upgrade RisingWave; this is an internal invariant and recent versions may handle empty commits gracefully."],"exampleFix":"// before\nlet result = DeltaLakeWriteResult::try_from(&sink_metadata)?;\n// after\nif matches!(&sink_metadata.metadata, Some(Serialized(_))) {\n    let result = DeltaLakeWriteResult::try_from(&sink_metadata)?;\n} else {\n    // skip empty commit\n    return Ok(());\n}","handlingStrategy":"validation","validationCode":"fn has_serialized_metadata(m: &SinkMetadata) -> bool {\n    matches!(m.metadata, Some(Serialized(_)))\n}","typeGuard":"fn as_serialized(m: &SinkMetadata) -> Option<&Vec<u8>> {\n    if let Some(Serialized(v)) = &m.metadata { Some(&v.metadata) } else { None }\n}","tryCatchPattern":"match DeltaLakeWriteResult::try_from(&meta) {\n    Ok(res) => commit(res),\n    Err(e) => log::warn!(\"empty/invalid delta sink metadata: {e}\"),\n}","preventionTips":["Always serialize adds in the sink writer before returning sink metadata.","Add a unit test covering commit with zero adds.","Assert metadata presence in debug builds before commit."],"tags":["rust","sink","deltalake","internal-invariant"],"backgroundTag":"empty-required-field","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"}