libnyanpasu/clash-nyanpasu · error
application actor reply dropped
Error message
application actor reply dropped
What it means
ApplicationClient.prepare_replace sends a PrepareReplace RPC with a reply port to the application actor; if the call returns CallResult::SenderError the reply port was dropped without an answer, surfaced as 'application actor reply dropped'. This typically means the actor is shutting down or its handler failed to reply.
Source
Thrown at backend/tauri/src/client/application.rs:113
self.replace_prepared_if_version(expected_version, prepared)
.await
}
pub(crate) async fn prepare_replace(
&self,
state: NyanpasuAppConfig,
) -> anyhow::Result<PreparedTypedReplace<NyanpasuAppConfig>> {
match self
.inner
.actor_ref
.call(
|reply| ApplicationActorMessage::PrepareReplace { state, reply },
None,
)
.await?
{
CallResult::Success(result) => result,
CallResult::SenderError => anyhow::bail!("application actor reply dropped"),
CallResult::Timeout => anyhow::bail!("application actor call timed out"),
}
}
pub(crate) async fn replace_prepared_if_version(
&self,
expected_version: u64,
prepared: PreparedTypedReplace<NyanpasuAppConfig>,
) -> anyhow::Result<ConditionalReplaceResult<ApplicationSnapshot>> {
match self
.inner
.actor_ref
.call(
|reply| ApplicationActorMessage::ReplacePreparedIfVersion {
expected_version,
prepared,
reply,
},View on GitHub (pinned to f7dbce2997)
Solutions
- Retry the replacement after confirming the application actor is running
- Check actor startup/supervision logs for shutdown at the time of the call
- Ensure the actor handler always replies to PrepareReplace, including on error paths
Defensive patterns
Strategy: retry
Validate before calling
if !app_client.is_actor_alive().await {
return Err(anyhow::anyhow!("application actor not running; skip replace"));
} Try / catch
match prepare_replace(state).await {
Ok(result) => result,
Err(e) if e.to_string().contains("reply dropped") => {
// actor likely shutting down; retry once after re-checking liveness
retry_prepare_replace(state).await
}
Err(e) => return Err(e),
} Prevention
- Ensure every actor handler replies to RPC ports on all paths
- Avoid issuing RPCs during shutdown/restart windows
- Use finite timeouts and treat SenderError as retryable-after-liveness-check
When it happens
Trigger: replace_if_version calling prepare_replace while the application actor is stopping, has crashed, or its message handler dropped the RpcReplyPort without sending a result.
Common situations: App version replacement raced with shutdown/restart, or actor supervision tore down the state actor mid-call.
Understand the failure class
Background: Request timed out: what client-side request timeouts mean across libraries (Request timed out, TIMED_OUT, APITimeoutError) — this error's family across 39 libraries.
Related errors
- clash config actor reply dropped
- clash config actor call timed out
- session state actor reply dropped
- result.error
- Failed to update
AI-assisted analysis of libnyanpasu/clash-nyanpasu@f7dbce2997 (2026-09-08).
Data as JSON: /api/errors/b5d57996774483c6.
Report an issue: GitHub.