{"record":{"id":"62a5cbc78660d0db","repo":"risingwavelabs/risingwave","slug":"channel-closed-0","errorCode":null,"errorMessage":"Channel closed: {0}","messagePattern":"Channel closed: (.+?)","errorType":"error_code","errorClass":"StreamExecutorError","httpStatus":null,"severity":"error","filePath":"src/stream/src/executor/error.rs","lineNumber":85,"sourceCode":"        BoxedError,\n    ),\n\n    #[error(\"Sink error: sink_id={1}, error: {0}\")]\n    SinkError(\n        #[source]\n        #[backtrace]\n        SinkError,\n        SinkId,\n    ),\n\n    #[error(transparent)]\n    RpcError(\n        #[from]\n        #[backtrace]\n        RpcError,\n    ),\n\n    #[error(\"Channel closed: {0}\")]\n    ChannelClosed(String),\n\n    #[error(transparent)]\n    ExchangeChannelClosed(\n        #[from]\n        #[backtrace]\n        ExchangeChannelClosed,\n    ),\n\n    #[error(\"Failed to align barrier: expected `{0:?}` but got `{1:?}`\")]\n    AlignBarrier(Box<Barrier>, Box<Barrier>),\n\n    #[error(\"Connector error: {0}\")]\n    ConnectorError(\n        #[source]\n        #[backtrace]\n        BoxedError,\n    ),","sourceCodeStart":67,"sourceCodeEnd":103,"githubUrl":"https://github.com/risingwavelabs/risingwave/blob/6469eb736d691e8e9b8a419a57edd6429ca77417/src/stream/src/executor/error.rs#L67-L103","documentation":"The ChannelClosed variant carries a human-readable message ('Channel closed: {0}') describing a closed internal channel inside the streaming executor. It indicates the executor tried to send or receive over a channel whose other end has been dropped, usually because a downstream/upstream actor has terminated.","triggerScenarios":"Created via ErrorKind::ChannelClosed(format!(...)) at points where the executor finds its exchange channel handle closed; e.g. sending barriers or chunks after the remote actor exited.","commonSituations":"A downstream actor panicked or failed and its channel receiver was dropped; actor rescale/kill during runtime; shutdown races where data is still in flight.","solutions":["Look at sibling actor logs to find why the peer actor terminated first (the root failure is usually upstream).","Check for panics or OOM kills in the compute node logs.","Rely on actor restart/failover to rebuild channels; investigate repeated closures for deterministic failures.","Ensure barrier alignment and termination logic closes channels gracefully rather than dropping them."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// before sending, check channel liveness\nif sender.is_closed() {\n    tracing::warn!(\"downstream channel already closed; skipping send\");\n    return Ok(());\n}","typeGuard":"fn is_channel_closed(e: &StreamExecutorError) -> bool {\n    e.variant_name() == \"ChannelClosed\"\n}","tryCatchPattern":"if let Err(e) = res {\n    if e.variant_name() == \"ChannelClosed\" {\n        // peer actor gone; let failover rebuild the graph\n        return Ok(());\n    }\n    return Err(e.into());\n}","preventionTips":["Ensure actors terminate via barrier-driven graceful stop, not abrupt drops.","Check peer actor health before long-lived sends.","Watch compute node logs for panics/OOM that kill peers.","Handle shutdown ordering so receivers outlive senders."],"tags":["channel","stream-executor","concurrency"],"backgroundTag":"broken-pipe","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"}