FuelLabs/fuel-core · error · anyhow::Error
{}
Error message
{} What it means
`get_all_peer_info` sends a `TaskRequest::GetAllPeerInfo` over an mpsc channel to the P2P service's background task and awaits the reply on a oneshot channel. The `"{}"` anyhow error wraps a `oneshot::error::RecvError`, which occurs only when the sender half was dropped before replying — i.e. the P2P task (or the code holding the reply sender) is gone. It therefore means the P2P service's internal task is no longer running to answer the query, not that peer data was unavailable.
Source
Thrown at crates/services/p2p/src/service.rs:1360
}
pub fn broadcast_preconfirmations(
&self,
preconfirmations: Arc<P2PPreConfirmationMessage>,
) -> anyhow::Result<()> {
self.request_sender
.try_send(TaskRequest::BroadcastPreConfirmations(preconfirmations))?;
Ok(())
}
pub async fn get_all_peers(&self) -> anyhow::Result<Vec<(PeerId, PeerInfo)>> {
let (sender, receiver) = oneshot::channel();
self.request_sender
.send(TaskRequest::GetAllPeerInfo { channel: sender })
.await?;
receiver.await.map_err(|e| anyhow!("{}", e))
}
pub async fn reserved_peer_network_height(
&self,
) -> anyhow::Result<Option<BlockHeight>> {
let (sender, receiver) = oneshot::channel();
self.request_sender
.send(TaskRequest::GetReservedPeerNetworkHeight { channel: sender })
.await?;
receiver.await.map_err(|e| anyhow!("{}", e))
}
pub fn subscribe_new_peers(&self) -> broadcast::Receiver<FuelPeerId> {
self.new_tx_subscription_broadcast.subscribe()
}
View on GitHub (pinned to add100d30d)
Solutions
- Check that the fuel-core P2P service is still running and has not been stopped before calling `get_all_peer_info`.
- Inspect P2P task logs for a panic or early exit in the request-processing loop and fix the underlying task crash.
- Treat the `RecvError` as a service-lifecycle signal: re-create/restart the P2P service instead of retrying the query against a dead task.
- If this occurs during shutdown races, guard call sites to not query the service once shutdown has begun.
Example fix
// before
let peers = p2p_service.get_all_peer_info().await?;
// after
if p2p_service.is_started() {
let peers = p2p_service.get_all_peer_info().await
.map_err(|e| e.context("P2P task dropped the peer-info reply; service likely stopped"))?;
} else {
return Err(anyhow!("P2P service is not running"));
} Defensive patterns
Strategy: try-catch
Validate before calling
// check service health before querying
if !p2p_service.is_started() {
return Err(anyhow!("P2P service not started; skipping get_all_peer_info"));
} Type guard
fn peers_reply_ok(res: &anyhow::Result<Vec<PeerInfo>>) -> bool {
res.as_ref().map(|p| !p.is_empty()).unwrap_or(false)
} Try / catch
match p2p_service.get_all_peer_info().await {
Ok(peers) => peers,
Err(e) if e.to_string().contains("channel closed") || e.to_string().contains("RecvError") => {
tracing::warn!("P2P task unavailable: {e:#}");
Vec::new() // or restart the service
}
Err(e) => return Err(e),
} Prevention
- Only call peer-info APIs while the P2P service task is confirmed running.
- Watch for node shutdown signals and stop querying services once shutdown begins.
- Log and alert on repeated channel-closed errors — they indicate the P2P task died.
- Keep a supervisor that restarts the P2P service after unexpected task termination.
When it happens
Trigger: Calling `P2PService::get_all_peer_info()` (service.rs:1360) after the P2P background task has stopped or is shutting down: the task loop exited, the `request_sender` channel send still succeeded (or the receiver was dropped concurrently), and the oneshot reply sender was dropped without sending.
Common situations: Node shutdown racing with an in-flight peer-info query; the P2P service task panicked or was aborted while the outer service handle is still alive; tests or code holding a stale `Service`/`Shared` handle after `stop()` was called.
Related errors
- The block height subscription channel was closed: {:?}
- No P2P service available
- Stream closed without transaction status
- Unsupported consensus: {:?}
AI-assisted analysis of FuelLabs/fuel-core@add100d30d (2026-09-05).
Data as JSON: /api/errors/c0ea6eb1172b1d79.
Report an issue: GitHub.