{"record":{"id":"0665621a10135d08","repo":"risingwavelabs/risingwave","slug":"invalid-commit-metadata-empty-payload","errorCode":null,"errorMessage":"Invalid commit metadata: empty payload","messagePattern":"Invalid commit metadata: empty payload","errorType":"exception","errorClass":"SinkError::Iceberg","httpStatus":null,"severity":"error","filePath":"src/connector/src/sink/iceberg/commit.rs","lineNumber":491,"sourceCode":"            \"iceberg_sink_commit_started\",\n        );\n\n        if commit_metadata.is_empty() {\n            tracing::debug!(\n                iceberg_component = \"sink_committer\",\n                iceberg_operation = \"commit\",\n                sink_id = %self.sink_id,\n                table = %self.table.identifier(),\n                epoch,\n                \"iceberg_sink_commit_skipped_empty_metadata\",\n            );\n            return Ok(());\n        }\n\n        // Deserialize commit metadata\n        let mut payload = deserialize_metadata(commit_metadata);\n        if payload.is_empty() {\n            return Err(SinkError::Iceberg(anyhow!(\n                \"Invalid commit metadata: empty payload\"\n            )));\n        }\n\n        // Last element is snapshot_id\n        let snapshot_id_bytes = payload.pop().ok_or_else(|| {\n            SinkError::Iceberg(anyhow!(\"Invalid commit metadata: missing snapshot_id\"))\n        })?;\n        let snapshot_id = i64::from_le_bytes(\n            snapshot_id_bytes\n                .try_into()\n                .map_err(|_| SinkError::Iceberg(anyhow!(\"Invalid snapshot id bytes\")))?,\n        );\n\n        // Remaining elements are write_results\n        let write_results = payload\n            .into_iter()\n            .map(|p| IcebergCommitResult::try_from_serialized_bytes(&p))","sourceCodeStart":473,"sourceCodeEnd":509,"githubUrl":"https://github.com/risingwavelabs/risingwave/blob/6469eb736d691e8e9b8a419a57edd6429ca77417/src/connector/src/sink/iceberg/commit.rs#L473-L509","documentation":"commit_data deserializes accumulated commit metadata via deserialize_metadata into a Vec<Vec<u8>> payload list. An empty list means no write result (and no trailing snapshot id) was collected for this commit, so there is nothing to commit; the code returns this SinkError::Iceberg instead of proceeding to the Iceberg table commit.","triggerScenarios":"commit_data invoked with an empty commit_metadata collection — e.g. the two-phase coordinator fires a commit without any preceding write results, or all metadata was filtered out upstream (the preceding `if ... return Ok(())` guard did not catch it).","commonSituations":"Coordinator/actor bugs where write results were never forwarded; state-store reads returning empty; sink epochs committed out of order.","solutions":["Ensure at least one write result is attached before invoking commit (check upstream guards that short-circuit on empty input)","Verify the two-phase/single-phase coordinator forwards collected metadata on commit","Inspect why deserialize_metadata returned an empty vec (corrupt vs genuinely empty input)"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"fn commit_metadata_ready(items: &[Vec<u8>]) -> bool {\n    !items.is_empty()\n}","typeGuard":null,"tryCatchPattern":"if commit_metadata.is_empty() {\n    tracing::warn!(\"no commit metadata; skipping commit\");\n    return Ok(());\n}\ncommit_data(commit_metadata).await?;","preventionTips":["Short-circuit commits when no write results were produced","Assert the coordinator forwards metadata from all epochs","Add metrics for empty commit attempts to detect coordinator bugs"],"tags":["rust","iceberg","commit","empty-input"],"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"}