charmbracelet/crush · error

failed to refetch Hyper provider: %w

Error message

failed to refetch Hyper provider: %w

What it means

RefetchHyperProvider re-fetches the Hyper provider catalog from the remote API after OAuth authentication. This error wraps any failure from hyperSyncer.Refetch(ctx), typically a network failure, HTTP error from the Hyper API, or a request rejected because the resolved API key (read live from config) is missing or invalid.

Source

Thrown at internal/config/store.go:201

// RefetchHyperProvider re-fetches the Hyper provider catalog from the
// remote API and updates the in-memory known providers list and config.
// This is called after OAuth authentication completes so the latest
// models are available without restarting.
func (s *ConfigStore) RefetchHyperProvider(ctx context.Context) error {
	// Build a fresh client that reads the API key from the live config,
	// not the stale snapshot captured at startup. The syncer's original
	// client closes over the startup config and would send an expired
	// token after OAuth re-authentication.
	freshClient := realHyperClient{
		baseURL:    hyperp.BaseURL(),
		resolveKey: func() string { return resolveHyperAPIKey(s.Config()) },
	}
	hyperSyncer.SetClient(freshClient)

	hyperProvider, err := hyperSyncer.Refetch(ctx)
	if err != nil {
		return fmt.Errorf("failed to refetch Hyper provider: %w", err)
	}
	if hyperProvider.ID == "" {
		return nil
	}

	s.writeMu.Lock()
	defer s.writeMu.Unlock()

	// Replace or insert the Hyper entry in knownProviders.
	found := false
	for i, p := range s.knownProviders {
		if string(p.ID) == string(hyperProvider.ID) {
			s.knownProviders[i] = hyperProvider
			found = true
			break
		}
	}
	if !found {

View on GitHub (pinned to 7944b8e522)

Solutions

  1. Check network connectivity / proxy settings and retry the authentication flow
  2. Verify a valid Hyper API key exists in the config (providers hyper api_key) before refetching
  3. Inspect the wrapped inner error (%w) to distinguish DNS/timeout vs HTTP status and act on it
  4. Retry later if the Hyper service is down; the rest of config still saved successfully

Example fix

// before
client := realHyperClient{baseURL: hyperp.BaseURL(), resolveKey: func() string { return os.Getenv("HYPER_API_KEY") }}
_ = store.RefetchHyperProvider(ctx)
// after
if resolveHyperAPIKey(store.Config()) == "" {
    return fmt.Errorf("hyper api key missing; skipping catalog refetch")
}
ctx, cancel := context.WithTimeout(ctx, 30*time.Second)
defer cancel()
if err := store.RefetchHyperProvider(ctx); err != nil {
    log.Warnf("hyper catalog refetch failed (models may be stale): %v", err)
}
Defensive patterns

Strategy: fallback

Validate before calling

if resolveHyperAPIKey(store.Config()) == "" {
    return errors.New("hyper api key not set; cannot refetch catalog")
}
if err := ctx.Err(); err != nil {
    return err
}

Type guard

func hasHyperKey(cfg *config.Config) bool {
    p, ok := cfg.Providers.Get("hyper")
    return ok && p.APIKey != ""
}

Try / catch

if err := store.RefetchHyperProvider(ctx); err != nil {
    log.Warnf("hyper catalog stale, continuing with cached models: %v", errors.Unwrap(err))
}

Prevention

When it happens

Trigger: Calling SetProviderAPIKey (or RefetchHyperProvider directly) after Hyper auth when the Hyper API is unreachable, returns a non-2xx response, the context is canceled/times out, or resolveHyperAPIKey yields an empty/expired key so the fresh client's request is rejected.

Common situations: No internet or behind a corporate proxy/firewall; Hyper API outage; user authenticated but the api_key was not persisted to config before the refetch; stale or revoked Hyper token; slow network exceeding the request timeout.

Related errors


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