BigPizzaV3/CodexPlusPlus · error

模型路由不能指向当前供应商自身:{model}

Error message

模型路由不能指向当前供应商自身:{model}

What it means

Thrown by select_model_route in crates/codex-plus-core/src/protocol_proxy.rs when a per-model route entry in the active relay's model_routes has target_relay_id equal to the active relay's own id. Routing a model to the source provider itself would recurse (the request would be selected and routed again), so the proxy rejects it upfront. The {model} placeholder names the model whose route triggered the error.

Source

Thrown at crates/codex-plus-core/src/protocol_proxy.rs:734

fn select_model_route(
    settings: &crate::settings::BackendSettings,
    model: &str,
) -> anyhow::Result<Option<ModelRouteSelection>> {
    if model.is_empty() || settings.active_aggregate_relay_profile().is_some() {
        return Ok(None);
    }

    let source = settings.active_relay_profile();
    let Some(route) = source
        .model_routes
        .iter()
        .find(|route| route.model.trim() == model)
    else {
        return Ok(None);
    };
    let target_relay_id = route.target_relay_id.trim();
    if target_relay_id == source.id {
        anyhow::bail!("模型路由不能指向当前供应商自身:{model}");
    }
    let target = settings
        .relay_profiles
        .iter()
        .find(|profile| profile.id == target_relay_id)
        .cloned()
        .with_context(|| format!("模型路由目标供应商不存在:{target_relay_id}"))?;
    if target.relay_mode == crate::settings::RelayMode::Aggregate {
        anyhow::bail!("模型路由目标不能是聚合供应商:{}", target.name);
    }
    if target.protocol != RelayProtocol::Responses {
        anyhow::bail!("模型路由目标必须使用 Responses API:{}", target.name);
    }

    let upstream_model = if route.target_model.trim().is_empty() {
        model.to_string()
    } else {
        route.target_model.trim().to_string()

View on GitHub (pinned to 1f431ae49b)

Solutions

  1. Open the active provider's model routes and change the target of the failing model to a different relay profile id
  2. If the intent was 'do not route this model', delete the route entry entirely instead of pointing it at itself
  3. After duplicating profiles, audit model_routes and rewrite target ids to the intended distinct profiles
  4. Add a save-time validation in the UI/manager that rejects route.target_relay_id == profile.id

Example fix

// settings.json (before): route targets the profile itself
"model_routes": [{ "model": "gpt-5", "target_relay_id": "relay-a" }]
// while active relay id is "relay-a"

// after: target a different profile
"model_routes": [{ "model": "gpt-5", "target_relay_id": "relay-b" }]
Defensive patterns

Strategy: validation

Validate before calling

fn route_targets_are_valid(profile: &RelayProfile) -> Result<(), String> {
    for route in &profile.model_routes {
        if route.target_relay_id.trim() == profile.id {
            return Err(format!("route for {} targets the profile itself", route.model));
        }
    }
    Ok(())
}

Try / catch

if let Err(e) = open_responses_proxy_request(body, path).await {
    if e.to_string().contains("不能指向当前供应商自身") {
        // open the model-routes editor for the active profile
    }
}

Prevention

When it happens

Trigger: Calling the Responses proxy with a model that has a model_routes entry whose target_relay_id is the source profile's id; copying a relay profile that kept its own id in model_routes after the copy became the new active profile.

Common situations: User duplicates a provider profile and the duplicated routes still point at the original id which is now itself; hand-editing settings.json relay ids without updating model_routes; UI allowing a self-referencing route to be saved.

Related errors


AI-assisted analysis of BigPizzaV3/CodexPlusPlus@1f431ae49b (2026-08-16). Data as JSON: /api/errors/e4dc0a8db13ccbc1. Report an issue: GitHub.