Hmbown/CodeWhale · error

Scope inventory reached its bound; delete narrower scopes…

Error message

Scope inventory reached its bound; delete narrower scopes explicitly

What it means

delete_all with no explicit scope list inventories every local scope under the operator's owner scope to delete them all. The store caps that inventory at 10,000 scopes; hitting the cap means a blanket delete would be unsafe or ambiguous, so the operation refuses and asks the caller to delete narrower scopes explicitly.

Solutions

  1. Call delete_all with an explicit, narrower list of scopes instead of None.
  2. Delete scopes in batches: enumerate scopes yourself, group them, and delete each group.
  3. Audit what is creating so many scopes and reduce scope granularity.
  4. If the bound is genuinely too small for your workload, raise the bound in code and document the change.

Example fix

// before
memory.delete_all(None)?; // Scope inventory reached its bound
// after
memory.delete_all(Some(vec![workspace_scope_hash]))?;
Defensive patterns

Strategy: validation

Validate before calling

let store = memory.open_structured()?;
let owner = Access::operator(vec![owner_scope()])?;
if store.local_scope_inventory(&owner)?.len() >= 10000 {
    // enumerate and delete narrower scopes explicitly instead
}

Prevention

When it happens

Trigger: Calling delete_all with scope=None when store.local_scope_inventory returns >= 10,000 scopes under the owner scope.

Common situations: Very large or long-lived memory stores where an agent created thousands of per-task or per-workspace scopes; runaway scope creation by automated tooling.

Understand the failure class

Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.

Related errors


AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22). Data as JSON: /api/errors/d0b7a4663c82b0e9. Report an issue: GitHub.

Appendix: source

Thrown at crates/tui/src/native_memory.rs:586

                }
                count += batch.len();
                after = batch.last().map(|m| m.id.clone());
            }
        }
        Ok(count)
    }
    pub fn delete_all(&self, scope: Option<MemoryScope>, workspace_id: Option<&str>) -> Result<()> {
        let scopes = match scope {
            Some(MemoryScope::Global) => vec![Self::owner_scope()],
            Some(MemoryScope::Workspace) => vec![Self::workspace_scope(
                workspace_id.ok_or_else(|| anyhow!("workspace id required"))?,
            )?],
            None => {
                let store = self.open_structured()?;
                let owner = Access::operator(vec![Self::owner_scope()])?;
                let mut scopes = store.local_scope_inventory(&owner)?;
                if scopes.len() >= 10000 {
                    bail!("Scope inventory reached its bound; delete narrower scopes explicitly");
                }
                if scopes.is_empty() {
                    scopes.push(Self::owner_scope());
                }
                scopes
            }
        };
        let access = Access::operator(scopes)?;
        let mut store = self.open_structured()?;
        loop {
            let batch = store.list(&access, None, 500)?;
            if batch.is_empty() {
                break;
            }
            for m in batch {
                match store.get(&access, &m.id) {
                    Ok(current) => {
                        store.forget(&access, &current.id, current.revision)?;

View on GitHub (pinned to 73e0f67d83)