wasmerio/wasmer · error · anyhow::Error
App deletion failed for an unknown reason
Error message
App deletion failed for an unknown reason
What it means
After issuing the delete_app mutation, the code checks res.success; if the backend reports the mutation did not succeed (without a more specific error), the library bails with 'App deletion failed for an unknown reason'. This is a catch-all for a failed mutation that returned no descriptive error.
Source
Thrown at lib/backend-api/src/query.rs:1978
Err(GraphQLApiFailure::from_errors(
"could not publish app",
res.errors,
))
}
}
/// Delete an app.
pub async fn delete_app(client: &WasmerClient, app_id: String) -> Result<(), anyhow::Error> {
let res = client
.run_graphql_strict(types::DeleteApp::build(types::DeleteAppVars {
app_id: app_id.into(),
}))
.await?
.delete_app
.context("API did not return data for the delete_app mutation")?;
if !res.success {
bail!("App deletion failed for an unknown reason");
}
Ok(())
}
/// Get all namespaces accessible by the current user.
pub async fn user_namespaces(
client: &WasmerClient,
) -> Result<Vec<types::Namespace>, anyhow::Error> {
let user = client
.run_graphql(types::GetCurrentUserWithNamespaces::build(
types::GetCurrentUserWithNamespacesVars {
namespace_role: None,
},
))
.await?
.viewer
.context("not logged in")?;View on GitHub (pinned to 8c4b9ee9d3)
Solutions
- Verify the auth token has delete permissions for the app's namespace.
- Check the app still exists and has no running instances/domains blocking deletion; stop instances first, then delete.
- Retry the delete once and inspect the app with get_app to confirm current state (it may have already been deleted).
- Report to Wasmer backend team if success=false persists with no error payload — the API should return a reason.
Example fix
// before
if !res.success {
bail!("App deletion failed for an unknown reason");
}
// after (caller-side guard)
let app = get_app(&client, &app_id).await.ok();
if app.is_some() {
delete_app(&client, &app_id).await?;
if get_app(&client, &app_id).await.is_ok() {
anyhow::bail!("app {app_id} still exists after deletion attempt");
}
} Defensive patterns
Strategy: try-catch
Try / catch
delete_app(&client, &app_id).await
.map_err(|e| anyhow::anyhow!("app deletion failed: {e:#}"))?;
// verify deletion actually took effect
if get_app(&client, &app_id).await.is_ok() {
anyhow::bail!("app {app_id} still exists after delete_app reported success");
} Prevention
- Ensure the token has delete permission on the app's namespace
- Stop running instances and detach domains before deleting
- Confirm the app via get_app before deleting; treat 'already gone' as success
When it happens
Trigger: Calling delete_app where the GraphQL mutation executes but returns success=false — typically due to insufficient permissions, the app already being deleted, or backend-side constraints (running instances, attached domains).
Common situations: Token lacking delete rights on the namespace; deleting an app twice in a race; app has live instances that the backend refuses to tear down silently.
Related errors
- cron job '{cron_job}' not found
- invalid node type returned
- No value found for secret with name '{}'
- The page is non-empty
- cannot create debug directory: {}
AI-assisted analysis of wasmerio/wasmer@8c4b9ee9d3 (2026-09-01).
Data as JSON: /api/errors/f589e1b2d02fa867.
Report an issue: GitHub.