astrid-runtime/astrid · error

delete of '{derived}' left unreclaimed state: {details}

Error message

delete of '{derived}' left unreclaimed state: {details}

What it means

Raised in teardown when the delete of the spawned derived agent leaves unreclaimed state: one or more cleanup steps recorded errors, which are joined into the details string. The command fails rather than silently leaving orphaned sessions/footprints behind.

Source

Thrown at crates/astrid-cli/src/commands/agent/spawn.rs:274

    let body = admin
        .request(AdminRequestKind::AgentDelete {
            principal: derived.clone(),
        })
        .await
        .with_context(|| format!("could not delete '{derived}'"))?;
    let outcome = into_result(body).with_context(|| format!("delete of '{derived}' failed"))?;
    if let astrid_events::kernel_api::AdminResponseBody::Success(value) = outcome
        && let Some(errors) = value
            .get("cleanup_errors")
            .and_then(|value| value.as_array())
        && !errors.is_empty()
    {
        let details = errors
            .iter()
            .filter_map(|error| error.as_str())
            .collect::<Vec<_>>()
            .join("; ");
        return Err(anyhow!(
            "delete of '{derived}' left unreclaimed state: {details}"
        ));
    }
    eprintln!("[spawn] tore down '{derived}' (footprint reclaimed)");
    Ok(())
}

/// First 8 hex chars of the session uuid — short but unique per spawn.
fn short_suffix(session: &SessionId) -> String {
    session.0.simple().to_string()[..8].to_string()
}

View on GitHub (pinned to affd8760f4)

Solutions

  1. Inspect the {details} suffix to see which state was unreclaimed
  2. Retry the delete/teardown once the agent is fully idle
  3. Manually delete the leftover session/workspace via the daemon admin commands

Example fix

null
Defensive patterns

Strategy: try-catch

Validate before calling

// ensure the agent is idle before teardown
if !agent_is_idle(&derived).await { wait_until_idle(&derived).await; }

Try / catch

match teardown(...).await { Err(e) if e.to_string().contains("left unreclaimed state") => { eprintln!("{e:#}; inspect details and retry delete"); manual_cleanup(&derived).await }, other => other }

Prevention

When it happens

Trigger: The delete call partially succeeded: e.g. the session could not be closed, workspace files could not be removed, or the daemon rejected the delete because the agent was still busy.

Common situations: Agent still processing a cancelled job when delete arrives, filesystem permissions preventing footprint reclamation, daemon connectivity hiccup during cleanup.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


AI-assisted analysis of astrid-runtime/astrid@affd8760f4 (2026-09-09). Data as JSON: /api/errors/74e268921fd20328. Report an issue: GitHub.