charmbracelet/crush · error

provider with ID %s not found in known providers

Error message

provider with ID %s not found in known providers

What it means

After saving a credential, SetProviderAPIKey needs to attach the credential to an in-memory provider config. If the provider ID is neither already configured nor found among the known (catwalk) providers, the store refuses to build a provider entry and returns this error.

Source

Thrown at internal/config/store.go:625

				foundProvider = &p
				break
			}
		}

		if foundProvider != nil {
			providerConfig = ProviderConfig{
				ID:           providerID,
				Name:         foundProvider.Name,
				BaseURL:      foundProvider.APIEndpoint,
				Type:         foundProvider.Type,
				Disable:      false,
				ExtraHeaders: make(map[string]string),
				ExtraParams:  make(map[string]string),
				Models:       foundProvider.Models,
			}
			setKeyOrToken()
		} else {
			return fmt.Errorf("provider with ID %s not found in known providers", providerID)
		}
		cfg.Providers.Set(providerID, providerConfig)
	}

	// After authenticating with Hyper, re-fetch the provider catalog so
	// the latest models are available without restarting.
	if providerID == "hyper" {
		if refetchErr := s.RefetchHyperProvider(context.Background()); refetchErr != nil {
			slog.Warn("Failed to refetch Hyper provider after auth", "error", refetchErr)
		}
	}
	return nil
}

// RefreshOAuthToken refreshes the OAuth token for the given provider.
//
// Providers like Hyper rotate refresh tokens: each exchange consumes the
// caller's refresh token, issues a new pair, and revokes the old one. If

View on GitHub (pinned to 7944b8e522)

Solutions

  1. Check the exact provider ID against the known catalog (crush models list) and fix the spelling/case
  2. Refresh the provider catalog so a newly added provider appears
  3. Define the provider explicitly in the config first, then set its API key
  4. Fall back to editing the config file manually to add providers.<id> with api_key

Example fix

// before
err := store.SetProviderAPIKey(ctx, scope, "anthropic", key) // actual ID: "anthropic"
// assume typo: "Anthropic"
// after
ids := []string{}
for _, p := range store.KnownProviders() { ids = append(ids, string(p.ID)) }
if !slices.Contains(ids, providerID) {
    return fmt.Errorf("unknown provider %q; known: %v", providerID, ids)
}
err := store.SetProviderAPIKey(ctx, scope, providerID, key)
Defensive patterns

Strategy: validation

Validate before calling

known := store.KnownProviders()
ids := make([]string, 0, len(known))
for _, p := range known { ids = append(ids, string(p.ID)) }
if _, cfgd := store.Config().Providers.Get(providerID); !cfgd && !slices.Contains(ids, providerID) {
    return fmt.Errorf("provider %q unknown; valid IDs: %v", providerID, ids)
}

Type guard

func providerExists(store *config.ConfigStore, id string) bool {
    if _, ok := store.Config().Providers.Get(id); ok { return true }
    for _, p := range store.KnownProviders() {
        if string(p.ID) == id { return true }
    }
    return false
}

Try / catch

if err := store.SetProviderAPIKey(ctx, scope, providerID, key); err != nil {
    if strings.Contains(err.Error(), "not found in known providers") {
        return fmt.Errorf("%w — run 'crush models' to list valid provider IDs", err)
    }
    return err
}

Prevention

When it happens

Trigger: Calling SetProviderAPIKey with a providerID that is misspelled, uses different casing, or refers to a custom/unknown provider that is absent from both cfg.Providers and the knownProviders catalog fetched from catwalk.

Common situations: Typo in the provider ID passed after `crush login <provider>`; a provider recently removed/renamed in the upstream catalog; custom provider defined only in a scope not being written; stale cached catalog missing a brand-new provider.

Related errors


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