Hmbown/CodeWhale · warning

saved cache route identity

Error message

saved cache route identity `{}` now resolves as {}/{} instead of {}/{}; send a new turn before warming

What it means

The cache-warmup path resolves the persisted provider route (`target`) again before warming. If the saved identity now resolves to a different provider or key than recorded, warming would prime the wrong provider's cache, so it bails and tells the user to send a new turn first (which re-captures a correct route).

Solutions

  1. Send a new turn first (as the message says) so a fresh, correct route is persisted, then run cache warmup
  2. Update the saved/provider configuration so the identity resolves to the same provider/key as when saved
  3. If the provider was intentionally changed, clear the stale cached route entry instead of replaying it
Defensive patterns

Strategy: validation

Validate before calling

let identity = config.resolve_persisted_provider_identity(
    Some(target.provider.as_str()), target.provider_id.as_deref())?;
if identity.provider != target.provider || identity.key != target.provider_identity {
    eprintln!("saved cache route is stale; send a new turn before warming");
    return;
}

Type guard

fn route_still_resolves(c: &Config, t: &CacheTarget) -> bool {
    c.resolve_persisted_provider_identity(
        Some(t.provider.as_str()), t.provider_id.as_deref())
        .map_or(false, |i| i.provider == t.provider && i.key == t.provider_identity)
}

Try / catch

match resolve_cache_replay_route(...).await {
    Err(e) if e.to_string().contains("now resolves as") => {
        // skip warmup; the next normal turn re-persists a valid route
        skip_warmup();
    }
    r => r,
}

Prevention

When it happens

Trigger: Calling `resolve_cache_replay_route` (via run_cache_warmup) when `resolve_persisted_provider_identity(target.provider, target.provider_id)` returns an identity whose `provider` or `key` differs from `target.provider`/`target.provider_identity` — e.g. a provider alias, profile, or default model changed since the route was saved.

Common situations: Auto model selection now picks a different provider after a config or model-registry update; provider renamed/re-registered; resuming a session saved before a provider change and running cache warmup immediately.

Related errors


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

Appendix: source

Thrown at crates/tui/src/tui/ui/provider_routes.rs:410

    ids.dedup();
    Ok(ids)
}

pub(crate) fn resolve_cache_replay_route(
    app: &App,
    config: &Config,
) -> Result<crate::route_runtime::ResolvedRuntimeRoute> {
    let target = app.cache_replay_target().ok_or_else(|| {
        anyhow::anyhow!("Auto has no concrete route yet; send a turn before warming its cache")
    })?;
    let identity = config
        .resolve_persisted_provider_identity(
            Some(target.provider.as_str()),
            target.provider_id.as_deref(),
        )
        .map_err(anyhow::Error::msg)?;
    if identity.provider != target.provider || identity.key != target.provider_identity {
        anyhow::bail!(
            "saved cache route identity `{}` now resolves as {}/{} instead of {}/{}; send a new turn before warming",
            target.provider_identity,
            identity.provider.as_str(),
            identity.key,
            target.provider.as_str(),
            target.provider_identity
        );
    }
    let route = resolve_runtime_route_for_identity(config, &identity, Some(&target.model))
        .map_err(anyhow::Error::msg)?;
    if let Some(previous_base_url) = target.base_url.as_deref() {
        let previous_endpoint = crate::route_receipt::endpoint_identity(previous_base_url);
        let current_endpoint =
            crate::route_receipt::endpoint_identity(&route.candidate.endpoint().base_url);
        if previous_endpoint != current_endpoint {
            anyhow::bail!(
                "the cache route endpoint changed since the last turn; send a new turn before warming"
            );

View on GitHub (pinned to 73e0f67d83)