{"record":{"id":"c6cba7a81830b405","repo":"risingwavelabs/risingwave","slug":"get-different-response-epoch-to-commit-epoch","errorCode":null,"errorMessage":"get different response epoch to commit epoch: {} {}","messagePattern":"get different response epoch to commit epoch: (.+?) (.+?)","errorType":"exception","errorClass":"RpcError","httpStatus":null,"severity":"error","filePath":"src/rpc_client/src/connector_client.rs","lineNumber":117,"sourceCode":"        self.send_request(SinkCoordinatorStreamRequest {\n            request: Some(sink_coordinator_stream_request::Request::Commit(\n                CommitMetadata { epoch, metadata },\n            )),\n        })\n        .await?;\n        match self.next_response().await? {\n            SinkCoordinatorStreamResponse {\n                response:\n                    Some(sink_coordinator_stream_response::Response::Commit(\n                        sink_coordinator_stream_response::CommitResponse {\n                            epoch: response_epoch,\n                        },\n                    )),\n            } => {\n                if epoch == response_epoch {\n                    Ok(())\n                } else {\n                    Err(RpcError::Internal(anyhow!(\n                        \"get different response epoch to commit epoch: {} {}\",\n                        epoch,\n                        response_epoch\n                    )))\n                }\n            }\n            msg => Err(RpcError::Internal(anyhow!(\n                \"should get Commit response but get {:?}\",\n                msg\n            ))),\n        }\n    }\n}\n","sourceCodeStart":99,"sourceCodeEnd":131,"githubUrl":"https://github.com/risingwavelabs/risingwave/blob/6469eb736d691e8e9b8a419a57edd6429ca77417/src/rpc_client/src/connector_client.rs#L99-L131","documentation":"commit in ConnectorClient received a CommitResponse whose epoch differs from the epoch being committed. The client asserts epoch equality as a safety invariant; on mismatch it returns RpcError::Internal with both epoch values.","triggerScenarios":"Calling commit(epoch) while the connector sink stream has a stale Commit response queued from a previous (aborted or retried) commit, so response_epoch != epoch.","commonSituations":"Retried commits after a timeout where the old response is still buffered in the stream; concurrent commit calls sharing one sink writer stream; epoch reuse after barrier failure.","solutions":["Discard/flush stale responses from the stream before committing (drain until a response matching the current epoch).","Do not share one ConnectorClient/sink stream across concurrent epoch commits; serialize commits per stream.","Log both epoch values and recreate the sink writer; a mismatch indicates the stream is out of sync and cannot be trusted."],"exampleFix":"// before\nif epoch == response_epoch { Ok(()) } else { Err(...) }\n// after: skip stale responses first\nloop {\n    match next_response().await? {\n        SinkWriterStreamResponse { response: Some(Response::Commit(rsp)) } => {\n            if rsp.epoch == epoch { break Ok(()); } // else: stale, keep draining\n        }\n        _ => continue,\n    }\n}","handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"loop {\n    match client.commit(epoch).await {\n        Ok(()) => break,\n        Err(e) if e.to_string().contains(\"different response epoch\") => {\n            // stale response in stream: recreate stream and retry\n            handle = recreate_sink_stream().await?;\n        }\n        Err(e) => return Err(e.into()),\n    }\n}","preventionTips":["Never share one sink stream across concurrent epoch commits.","After any commit timeout, recreate the stream instead of reusing it.","Ensure epochs strictly increase per stream session."],"tags":["grpc","streaming","sink","epoch","rpc"],"backgroundTag":"unexpected-response-shape","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"}