aaif-goose/goose · error

Failed to create token counter: {}

Error message

Failed to create token counter: {}

What it means

check_if_compaction_needed prefers session.usage.total_tokens (source 'session metadata') and only falls back to local estimation when usage is None. In that fallback it must build a token counter via create_token_counter; failure of that construction is re-wrapped with this message, preserving the underlying error text.

Source

Thrown at crates/goose/src/context_mgmt/mod.rs:257

            .get_param::<f64>("GOOSE_AUTO_COMPACT_THRESHOLD")
            .unwrap_or(DEFAULT_COMPACTION_THRESHOLD)
    });

    let model_config = session
        .model_config
        .clone()
        .unwrap_or_else(|| ModelConfig::new("unknown"));
    let context_limit = provider
        .get_context_limit(&model_config)
        .await
        .unwrap_or_else(|_| model_config.context_limit());

    let (current_tokens, _token_source) = match session.usage.total_tokens {
        Some(tokens) => (tokens as usize, "session metadata"),
        None => {
            let token_counter = create_token_counter()
                .await
                .map_err(|e| anyhow::anyhow!("Failed to create token counter: {}", e))?;

            let token_counts: Vec<_> = messages
                .iter()
                .filter(|m| m.is_agent_visible())
                .map(|msg| token_counter.count_chat_tokens("", std::slice::from_ref(msg), &[]))
                .collect();

            (token_counts.iter().sum(), "estimated")
        }
    };

    let usage_ratio = current_tokens as f64 / context_limit as f64;

    let needs_compaction = if threshold <= 0.0 || threshold >= 1.0 {
        false // Auto-compact is disabled.
    } else {
        usage_ratio > threshold
    };

View on GitHub (pinned to 3810898a74)

Solutions

  1. Inspect the wrapped error text for the concrete initialization failure
  2. Restore tokenizer availability (network/cache) so estimation can run
  3. Use sessions that carry usage metadata (total_tokens), which skips counter creation entirely
Defensive patterns

Strategy: fallback

Validate before calling

// Skip estimation when trustworthy usage metadata exists:
if session.usage.total_tokens.is_none() {
    create_token_counter().await?; // fail fast here, not inside the compaction check
}
check_if_compaction_needed(provider, &model_config, &session, &messages).await?;

Try / catch

match check_if_compaction_needed(...).await {
    Err(e) if e.to_string().contains("Failed to create token counter") => {
        // treat compaction as not-yet-needed and retry after the counter issue is fixed,
        // or compute a conservative estimate from message lengths
    }
    other => other?,
}

Prevention

When it happens

Trigger: A session whose metadata lacks total_tokens (older sessions, providers that do not report usage) on a machine where create_token_counter fails — e.g. tokenizer download/init blocked by network or a corrupted cache.

Common situations: Offline environments; sessions created by older goose versions without usage tracking; provider outages that also prevent tokenizer fetches.

Related errors


AI-assisted analysis of aaif-goose/goose@3810898a74 (2026-08-16). Data as JSON: /api/errors/46f95f7ba2f6e73a. Report an issue: GitHub.