block/buzz · error · anyhow::Error

request has not crossed the explicit approval boundary

Error message

request has not crossed the explicit approval boundary

What it means

The deletion state machine only permits execution past an explicit approval boundary. validate/execute paths accept requests in approved-or-later stages (down through RetentionPending/Aborted handling); a request still in DeletionStage::Submitted or DeletionStage::Inventoried has not been approved by an operator, so attempting to progress it bails with this message. The two-phase design is deliberate: destructive, fleet-wide erasure must never run from a bare submit, and inventory must be reviewed before approval (the frozen-inventory validation runs for approved requests).

Source

Thrown at crates/buzz-deletion/src/lib.rs:1244

                    &token,
                    serde_json::json!({"postgres": true, "object_store": true, "redis": true}),
                )
                .await?;
        }
        DeletionStage::LogicallyVerified => {
            validate_frozen_inventory(request)?;
            services
                .store
                .mark_retention_pending(
                    &token,
                    serde_json::json!({
                        "policy": "member-erasure and fleet-wide shared-CAS GC are out of V1 scope"
                    }),
                )
                .await?;
        }
        DeletionStage::Submitted | DeletionStage::Inventoried => {
            anyhow::bail!("request has not crossed the explicit approval boundary")
        }
        DeletionStage::RetentionPending | DeletionStage::Aborted => {}
    }
    Ok(())
}

fn token_with_current_fence(token: &LeaseToken, request: &DeletionRequest) -> LeaseToken {
    LeaseToken {
        fence_generation: request.fence_generation,
        ..token.clone()
    }
}

/// Prove logical absence by listing each tenant prefix and requiring it
/// empty — O(1) requests per prefix, independent of fleet size.
async fn verify_storage_absence(services: &Services, request: &DeletionRequest) -> Result<()> {
    for prefix in tenant_prefixes(*request.community_id.as_uuid()) {
        let page = services.media.list_prefix_page(&prefix, None, 1).await?;

View on GitHub (pinned to f956e6fe06)

Solutions

  1. Advance the request through the approval step first: `buzz-deletion approve --id <request-id>` (with whatever authorisation your runbook requires), then re-run execution.
  2. Verify the request's current stage (store listing/admin output) and operate on the id you actually approved — approve-then-run with mismatched ids is the classic slip.
  3. If the request should not proceed, abort it instead of trying to force execution; approved-boundary checks are intentional and not bypassable by retry.
  4. For automation, encode submit → (review inventory) → approve → run as separate steps with an explicit gate between submit and approve.

Example fix

# before
buzz-deletion submit --host localhost:3000 --requester npub1... --reason gdpr  # -> id R
buzz-deletion run --id R
# error: request has not crossed the explicit approval boundary

# after
buzz-deletion submit --host localhost:3000 --requester npub1... --reason gdpr  # -> id R
buzz-deletion approve --id R
buzz-deletion run --id R
Defensive patterns

Strategy: validation

Validate before calling

# before executing, require an approved-or-later stage
stage=$(psql -tA "$DATABASE_URL" -c "SELECT stage FROM deletion_requests WHERE id='<uuid>';" )
if [[ "$stage" == "submitted" || "$stage" == "inventoried" ]]; then
  echo "request <uuid> not approved yet — run approve first" >&2; exit 1
fi

Type guard

function isApprovedStage(stage: string): boolean {
  return !['submitted', 'inventoried'].includes(stage);
}

Prevention

When it happens

Trigger: Calling the run/execute path (or certain stage transitions) against a request that was submitted but never approved — e.g. `buzz-deletion run --id <uuid>` right after `submit`, or an automation tool driving stage transitions directly via the store API while the request is still Submitted/Inventoried.

Common situations: Scripts that chain submit+run and skip the approve step (or call approve against the wrong id); a request re-created after abort so its old id is reused by a stale runbook; operators assuming inventory implies approval.

Related errors


AI-assisted analysis of block/buzz@f956e6fe06 (2026-08-16). Data as JSON: /api/errors/5e460ca60aecb3d5. Report an issue: GitHub.