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

  1. Verify the auth token has delete permissions for the app's namespace.
  2. Check the app still exists and has no running instances/domains blocking deletion; stop instances first, then delete.
  3. Retry the delete once and inspect the app with get_app to confirm current state (it may have already been deleted).
  4. 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

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


AI-assisted analysis of wasmerio/wasmer@8c4b9ee9d3 (2026-09-01). Data as JSON: /api/errors/f589e1b2d02fa867. Report an issue: GitHub.