{"record":{"id":"0daed9d281b6efec","repo":"charmbracelet/crush","slug":"failed-to-fetch-providers-from-catwalk-w","errorCode":null,"errorMessage":"failed to fetch providers from Catwalk: %w","messagePattern":"failed to fetch providers from Catwalk: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/config/provider.go","lineNumber":69,"sourceCode":"\t\treturn filepath.Join(localAppData, appName, name+\".json\")\n\t}\n\n\treturn filepath.Join(home.Dir(), \".local\", \"share\", appName, name+\".json\")\n}\n\n// UpdateProviders updates the Catwalk providers list from a specified source.\nfunc UpdateProviders(pathOrURL string) error {\n\tvar providers []catwalk.Provider\n\tpathOrURL = cmp.Or(pathOrURL, os.Getenv(\"CATWALK_URL\"), defaultCatwalkURL)\n\n\tswitch {\n\tcase pathOrURL == \"embedded\":\n\t\tproviders = embedded.GetAll()\n\tcase strings.HasPrefix(pathOrURL, \"http://\") || strings.HasPrefix(pathOrURL, \"https://\"):\n\t\tvar err error\n\t\tproviders, err = catwalk.NewWithURL(pathOrURL).GetProviders(context.Background(), \"\")\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"failed to fetch providers from Catwalk: %w\", err)\n\t\t}\n\tdefault:\n\t\tcontent, err := os.ReadFile(pathOrURL)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"failed to read file: %w\", err)\n\t\t}\n\t\tif err := json.Unmarshal(content, &providers); err != nil {\n\t\t\treturn fmt.Errorf(\"failed to unmarshal provider data: %w\", err)\n\t\t}\n\t\tif len(providers) == 0 {\n\t\t\treturn fmt.Errorf(\"no providers found in the provided source\")\n\t\t}\n\t}\n\n\tif err := newCache[[]catwalk.Provider](cachePathFor(\"providers\")).Store(providers); err != nil {\n\t\treturn fmt.Errorf(\"failed to save providers to cache: %w\", err)\n\t}\n","sourceCodeStart":51,"sourceCodeEnd":87,"githubUrl":"https://github.com/charmbracelet/crush/blob/7944b8e52225d8805e31eacbf7ef24856b0dfb7a/internal/config/provider.go#L51-L87","documentation":"UpdateProviders resolves the provider catalog from a source: the embedded snapshot, an http(s) URL fetched via catwalk, or a local JSON file. This error is returned when the catwalk HTTP client fails to GET the providers endpoint at the given URL, wrapping the network/HTTP error. It means no provider list could be downloaded, so the config cannot resolve providers/models.","triggerScenarios":"Calling config.UpdateProviders with a pathOrURL starting with http:// or https:// when the Catwalk server is unreachable, returns 5xx, DNS fails, TLS fails, or the request context is cancelled.","commonSituations":"Pointing the provider source at a self-hosted catwalk instance with a wrong port or hostname; offline/behind a corporate proxy; the catwalk service being down during `crush update-providers` or app startup with autoupdate enabled.","solutions":["Check network reachability: `curl -v <url>` to reproduce the underlying error shown after %w.","Fix the URL (scheme, host, port) in the config or CLI flag.","Set HTTP proxy env vars (HTTPS_PROXY) if behind a corporate proxy.","Use a local JSON file path or the \"embedded\" source as a fallback and retry later."],"exampleFix":"// before\nerr := config.UpdateProviders(\"https://catwalk.internal.example:9000\")\n// after\nif err := config.UpdateProviders(\"https://catwalk.internal.example:9000\"); err != nil {\n    slog.Warn(\"falling back to embedded providers\", \"err\", err)\n    err = config.UpdateProviders(\"embedded\")\n}","handlingStrategy":"try-catch","validationCode":"u, err := url.Parse(src)\nif err != nil || (u.Scheme != \"http\" && u.Scheme != \"https\") { /* validate URL before use */ }\nresp, err := http.Head(u.String())\nif err != nil || resp.StatusCode >= 500 { /* surface connectivity problem before UpdateProviders */ }","typeGuard":null,"tryCatchPattern":"providers, err := fetchFromCatwalk(ctx, url)\nif err != nil {\n    var netErr net.Error\n    switch {\n    case errors.As(err, &netErr):\n        slog.Warn(\"catwalk unreachable, retrying with backoff\", \"err\", err)\n    case errors.Is(err, context.DeadlineExceeded):\n        slog.Warn(\"catwalk fetch timed out\")\n    }\n    return err\n}","preventionTips":["Curl the catwalk URL as a smoke test before wiring it into config.","Set HTTPS_PROXY in corporate environments.","Cache the last-good provider list so startup can fall back when offline.","Add a retry with exponential backoff around UpdateProviders for transient failures."],"tags":["network","http","catwalk","providers"],"backgroundTag":"http-request-failed","analyzedSha":"7944b8e52225d8805e31eacbf7ef24856b0dfb7a","analyzedAt":"2026-08-29T12:48:59.079Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}