charmbracelet/crush · error

%s model: model %q found in multiple providers: %s. Please s

Error message

%s model: model %q found in multiple providers: %s. Please specify provider using 'provider/model' format

What it means

validateModelMatches (internal/cmd/run.go:660) returns this error when the given model ID matches models in more than one enabled provider, making the selection ambiguous. Crush requires disambiguation via the 'provider/model' syntax since model IDs are only unique within a provider.

Source

Thrown at internal/cmd/run.go:660

		return false
	}
	if wantProvider != "" && wantProvider != providerName {
		return false
	}
	return strings.EqualFold(modelID, wantID)
}

// validateModelMatches ensures exactly one match exists.
func validateModelMatches(matches []modelMatch, modelID, label string) (modelMatch, error) {
	switch {
	case len(matches) == 0:
		return modelMatch{}, fmt.Errorf("%s model %q not found", label, modelID)
	case len(matches) > 1:
		names := make([]string, len(matches))
		for i, m := range matches {
			names[i] = m.provider
		}
		return modelMatch{}, fmt.Errorf(
			"%s model: model %q found in multiple providers: %s. Please specify provider using 'provider/model' format",
			label, modelID, strings.Join(names, ", "),
		)
	}
	return matches[0], nil
}

// resolveSession returns the session to use for a non-interactive run.
// If continueSessionID is set it fetches that session; if useLast is set it
// returns the most recently updated top-level session; otherwise it creates a
// new one.
func resolveSession(ctx context.Context, c *client.Client, wsID, continueSessionID string, useLast bool) (*proto.Session, error) {
	switch {
	case continueSessionID != "":
		sess, err := c.GetSession(ctx, wsID, continueSessionID)
		if err != nil {
			return nil, fmt.Errorf("session not found: %s", continueSessionID)
		}

View on GitHub (pinned to 7944b8e522)

Solutions

  1. Re-run with the qualified form: --model "provider/model" (e.g. "openai/gpt-4o")
  2. Use the provider names listed in the error message to pick the intended one
  3. Disable the duplicate/unwanted provider in config if you never use it
  4. Run `crush models` to see which providers offer the model

Example fix

// before
crush run --model "gpt-4o"
// error: found in multiple providers: openai, openrouter
// after
crush run --model "openai/gpt-4o"
Defensive patterns

Strategy: validation

Validate before calling

// Count providers offering the bare model ID before invoking
matches := 0
for name, p := range providers {
	if p.Disable {
		continue
	}
	for _, m := range p.Models {
		if strings.EqualFold(m.ID, modelID) {
			matches++
		}
	}
}
if matches > 1 && !strings.Contains(modelID, "/") {
	modelID = preferredProvider + "/" + modelID
}

Prevention

When it happens

Trigger: --model or --small-model given as a bare model ID (no '/'); two or more enabled providers each list a model whose ID matches case-insensitively; validateModelMatches receives len(matches) > 1.

Common situations: Common IDs shared across providers (e.g. 'gpt-4o' via OpenAI and OpenRouter, 'claude-3-5-sonnet' via Anthropic and Bedrock); multiple gateways configured for the same upstream model; newly added provider duplicating an existing model ID.

Related errors


AI-assisted analysis of charmbracelet/crush@7944b8e522 (2026-08-29). Data as JSON: /api/errors/7038aff7ad0f9929. Report an issue: GitHub.