charmbracelet/crush · error

%s model %q not found

Error message

%s model %q not found

What it means

validateModelMatches (internal/cmd/run.go:654) returns this error when findModelMatches found zero enabled providers offering a model matching the given --model or --small-model string. The match is case-insensitive on model ID across all non-disabled providers.

Source

Thrown at internal/cmd/run.go:654

}

// matchesModel returns true if the model ID matches the filter
// criteria.
func matchesModel(wantID, wantProvider, modelID, providerName string) bool {
	if wantID == "" {
		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) {

View on GitHub (pinned to 7944b8e522)

Solutions

  1. Run `crush models` to list available provider/model IDs and copy the exact ID
  2. Fix typos — matching is case-insensitive but must otherwise be exact
  3. Enable the provider and set its API key in config (crushrc `provider` / `model` builtins or crush.json)
  4. If using 'provider/model', verify the provider name matches the configured provider key
  5. Check whether the model was renamed/deprecated upstream and pick the successor

Example fix

// before
crush run --model "anthropic/claude-sonnet-4-5"
// error: large model "claude-sonnet-4-5" not found
// after: use exact ID from `crush models`
crush run --model "anthropic/claude-sonnet-4-5-20250929"
Defensive patterns

Strategy: validation

Validate before calling

// Pre-validate the model string against provider config
// (mirror of findModelMatches logic)
func modelExists(providers map[string]config.ProviderConfig, s string) bool {
	prov, id := parseModelString(s)
	for name, p := range providers {
		if p.Disable || (prov != "" && name != prov) {
			continue
		}
		for _, m := range p.Models {
			if strings.EqualFold(m.ID, id) {
				return true
			}
		}
	}
	return false
}

Prevention

When it happens

Trigger: runNonInteractive with --model/--small-model; after scanning all enabled providers' model lists, no model ID equals (case-insensitively) the requested ID, or the provider part of 'provider/model' does not match any configured provider name.

Common situations: Typo in the model ID; provider missing API key / disabled in config; model deprecated or renamed upstream; using a provider alias that is not the configured provider name; 'provider/model' string where provider part doesn't match.

Related errors


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