{"record":{"id":"093a96eb4b9c7679","repo":"charmbracelet/crush","slug":"failed-to-refetch-hyper-provider-w","errorCode":null,"errorMessage":"failed to refetch Hyper provider: %w","messagePattern":"failed to refetch Hyper provider: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/config/store.go","lineNumber":201,"sourceCode":"\n// RefetchHyperProvider re-fetches the Hyper provider catalog from the\n// remote API and updates the in-memory known providers list and config.\n// This is called after OAuth authentication completes so the latest\n// models are available without restarting.\nfunc (s *ConfigStore) RefetchHyperProvider(ctx context.Context) error {\n\t// Build a fresh client that reads the API key from the live config,\n\t// not the stale snapshot captured at startup. The syncer's original\n\t// client closes over the startup config and would send an expired\n\t// token after OAuth re-authentication.\n\tfreshClient := realHyperClient{\n\t\tbaseURL:    hyperp.BaseURL(),\n\t\tresolveKey: func() string { return resolveHyperAPIKey(s.Config()) },\n\t}\n\thyperSyncer.SetClient(freshClient)\n\n\thyperProvider, err := hyperSyncer.Refetch(ctx)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to refetch Hyper provider: %w\", err)\n\t}\n\tif hyperProvider.ID == \"\" {\n\t\treturn nil\n\t}\n\n\ts.writeMu.Lock()\n\tdefer s.writeMu.Unlock()\n\n\t// Replace or insert the Hyper entry in knownProviders.\n\tfound := false\n\tfor i, p := range s.knownProviders {\n\t\tif string(p.ID) == string(hyperProvider.ID) {\n\t\t\ts.knownProviders[i] = hyperProvider\n\t\t\tfound = true\n\t\t\tbreak\n\t\t}\n\t}\n\tif !found {","sourceCodeStart":183,"sourceCodeEnd":219,"githubUrl":"https://github.com/charmbracelet/crush/blob/7944b8e52225d8805e31eacbf7ef24856b0dfb7a/internal/config/store.go#L183-L219","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Check network connectivity / proxy settings and retry the authentication flow","Verify a valid Hyper API key exists in the config (providers hyper api_key) before refetching","Inspect the wrapped inner error (%w) to distinguish DNS/timeout vs HTTP status and act on it","Retry later if the Hyper service is down; the rest of config still saved successfully"],"exampleFix":"// before\nclient := realHyperClient{baseURL: hyperp.BaseURL(), resolveKey: func() string { return os.Getenv(\"HYPER_API_KEY\") }}\n_ = store.RefetchHyperProvider(ctx)\n// after\nif resolveHyperAPIKey(store.Config()) == \"\" {\n    return fmt.Errorf(\"hyper api key missing; skipping catalog refetch\")\n}\nctx, cancel := context.WithTimeout(ctx, 30*time.Second)\ndefer cancel()\nif err := store.RefetchHyperProvider(ctx); err != nil {\n    log.Warnf(\"hyper catalog refetch failed (models may be stale): %v\", err)\n}","handlingStrategy":"fallback","validationCode":"if resolveHyperAPIKey(store.Config()) == \"\" {\n    return errors.New(\"hyper api key not set; cannot refetch catalog\")\n}\nif err := ctx.Err(); err != nil {\n    return err\n}","typeGuard":"func hasHyperKey(cfg *config.Config) bool {\n    p, ok := cfg.Providers.Get(\"hyper\")\n    return ok && p.APIKey != \"\"\n}","tryCatchPattern":"if err := store.RefetchHyperProvider(ctx); err != nil {\n    log.Warnf(\"hyper catalog stale, continuing with cached models: %v\", errors.Unwrap(err))\n}","preventionTips":["Verify the Hyper API key exists in config before triggering refetch","Always pass a context with a sane timeout for network operations","Treat catalog refetch as non-fatal — fall back to cached models","Monitor network/proxy availability in environments behind firewalls"],"tags":["network","http","provider-catalog","hyper"],"backgroundTag":"provider-api-request-failed","analyzedSha":"7944b8e52225d8805e31eacbf7ef24856b0dfb7a","analyzedAt":"2026-08-29T12:48:59.079Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}