libnyanpasu/clash-nyanpasu · error
proxy actor is unavailable
Error message
proxy actor is unavailable
What it means
Thrown by the proxies service `call` helper when a request to the proxy actor fails for any reason other than success or timeout — typically because the actor is not running, has crashed, or its mailbox/channel is unavailable. Unlike the timeout case, the operation is definitively not in flight, so calls fail fast. Callers of `get`, `providers`, `select`, and `update_provider` all funnel through this error when the actor layer is down.
Source
Thrown at backend/tauri/src/core/proxies.rs:331
snapshots: snapshot_rx,
changes: changes_rx,
})))
}
async fn call<T: Send + 'static>(
&self,
message: impl FnOnce(RpcReplyPort<Result<T>>) -> Message,
) -> Result<T> {
match self
.0
.actor
.call(message, Some(Duration::from_secs(120)))
.await
{
Ok(ractor::rpc::CallResult::Success(result)) => result,
Ok(ractor::rpc::CallResult::Timeout) => anyhow::bail!(
"proxy actor timed out; an operation may still be running, do not replay mutations automatically"
),
_ => anyhow::bail!("proxy actor is unavailable"),
}
}
pub async fn get(&self, force: bool) -> Result<Proxies> {
let snapshot = self.call(|reply| Message::Read { force, reply }).await?;
anyhow::ensure!(
!snapshot.api.is_revoked(),
"proxy snapshot belongs to a retired instance"
);
Ok(snapshot.proxies.clone())
}
pub async fn providers(&self) -> Result<api::ProvidersProxiesRes> {
let snapshot = self
.call(|reply| Message::Read {
force: false,
reply,
})
.await?;
anyhow::ensure!(View on GitHub (pinned to f7dbce2997)
Solutions
- Restart the application (or the actor via the app's restart path) so the proxy actor is respawned and the client gets a live reference.
- Ensure `NyanpasuClient`/`AppSupervisor` bootstrap completed before issuing proxy operations; check startup logs for actor spawn failures.
- If shutdown races cause it, add graceful shutdown ordering so stop signals wait for in-flight proxy calls to drain.
Example fix
// before: calling proxies API during/after shutdown
let proxies = client.get_proxies().await?; // actor already stopped
// after: ensure bootstrap/actor liveness before use
if client.is_ready().await {
let proxies = client.get_proxies().await?;
} else {
anyhow::bail!("proxy actor not started; complete bootstrap first");
} Defensive patterns
Strategy: fallback
Validate before calling
// Check client/actor readiness before issuing proxy calls
if !client.is_ready().await {
eprintln!("proxy actor unavailable: complete bootstrap before calling proxies API");
} Try / catch
match client.get_proxies().await {
Err(e) if e.to_string().contains("proxy actor is unavailable") => {
// actor dead — restart app/core; do not spam retries
eprintln!("restarting core to recover proxy actor");
client.restart_core().await?;
}
other => other?,
} Prevention
- Ensure NyanpasuClient bootstrap fully completes before exposing proxy APIs to the UI
- Check startup logs for actor spawn failures after upgrades
- Order shutdown so in-flight proxy RPCs drain before stopping the actor
- Treat this as non-retryable per-attempt: recover by restarting the actor/core, not re-sending
When it happens
Trigger: Any of `get`, `providers`, `select`, or `update_provider` calling `call(...)` when `actor.call(...)` returns an `Err` (send failure / dead actor) or a `CallResult` other than `Success`/`Timeout`, e.g. the actor was never spawned or was stopped during supervision shutdown.
Common situations: The app is shutting down and the actor was stopped mid-request; actor startup failed at bootstrap so the client holds a dead `ActorRef`; a supervision/crash took the actor down; calling the client before `NyanpasuClient` bootstrap finished.
Understand the failure class
Background: ECONNREFUSED and "connection refused" / "could not connect to server" errors: what they mean and how to fix them — this error's family across 44 libraries.
Related errors
- proxy actor timed out; an operation may still be running, do
- proxy snapshot belongs to a retired instance
- application actor reply dropped
- application actor call timed out
- clash config actor reply dropped
AI-assisted analysis of libnyanpasu/clash-nyanpasu@f7dbce2997 (2026-09-08).
Data as JSON: /api/errors/762da8a0de33d5b7.
Report an issue: GitHub.