{"record":{"id":"cd1d595738bba291","repo":"risingwavelabs/risingwave","slug":"google-pub-sub-sink-error-missing-value-to-publis","errorCode":null,"errorMessage":"Google Pub/Sub sink error: missing value to publish","messagePattern":"Google Pub/Sub sink error: missing value to publish","errorType":"error_code","errorClass":"SinkError::GooglePubSub","httpStatus":null,"severity":"error","filePath":"src/connector/src/sink/google_pubsub.rs","lineNumber":336,"sourceCode":"}\n\nimpl FormattedSink for GooglePubSubPayloadWriter<'_> {\n    type K = String;\n    type V = Vec<u8>;\n\n    async fn write_one(&mut self, k: Option<Self::K>, v: Option<Self::V>) -> Result<()> {\n        let ordering_key = k.unwrap_or_default();\n        match v {\n            Some(data) => {\n                let msg = PubsubMessage {\n                    data,\n                    ordering_key,\n                    ..Default::default()\n                };\n                self.message_vec.push(msg);\n                Ok(())\n            }\n            None => Err(SinkError::GooglePubSub(anyhow!(\n                \"Google Pub/Sub sink error: missing value to publish\"\n            ))),\n        }\n    }\n}\n","sourceCodeStart":318,"sourceCodeEnd":342,"githubUrl":"https://github.com/risingwavelabs/risingwave/blob/6469eb736d691e8e9b8a419a57edd6429ca77417/src/connector/src/sink/google_pubsub.rs#L318-L342","documentation":"During `write_one`, the sink expects to extract a value from the event to publish as the message body, but the value slot was `None`. The sink refuses to publish an empty/absent payload and returns this error instead.","triggerScenarios":"Writing a row/event where the payload-producing expression yields None — e.g. a NULL value in a single-column payload schema, or a formatting step that produced no value.","commonSituations":"Inserting NULL into the payload column of an HTTP/Pub/Sub style sink; upstream Debezium/encoder emitting null for deletes in non-append-only mode; schema mismatch between the materialized view and sink expectation.","solutions":["Ensure the payload column is NOT NULL in the source/materialized view","Filter out NULL rows before the sink (e.g. WHERE payload IS NOT NULL in the MV)","Use an appropriate encoder/format that always produces a value for the event type","If deletes produce null payloads, enable the sink's append-only/ignore-delete handling"],"exampleFix":"// before\nCREATE MATERIALIZED VIEW mv AS SELECT nullable_payload FROM src;\n// after\nCREATE MATERIALIZED VIEW mv AS SELECT nullable_payload FROM src WHERE nullable_payload IS NOT NULL;","handlingStrategy":"validation","validationCode":"CREATE MATERIALIZED VIEW mv AS\nSELECT payload FROM src WHERE payload IS NOT NULL;","typeGuard":null,"tryCatchPattern":"match sink.write_one(event).await {\n    Err(e) if e.to_string().contains(\"missing value to publish\") => {\n        log::warn!(\"skipping null-payload event\");\n    }\n    r => r?,\n}","preventionTips":["Declare payload columns NOT NULL at the source","Filter NULL payloads out upstream of the sink","Audit encoder output for delete/tombstone events"],"tags":["pubsub","null-value","payload","sink","data-quality"],"backgroundTag":"null-argument","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"}