{"record":{"id":"169299b1fb40e596","repo":"charmbracelet/crush","slug":"empty-providers-list-from-catwalk","errorCode":null,"errorMessage":"empty providers list from catwalk","messagePattern":"empty providers list from catwalk","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"internal/config/catwalk.go","lineNumber":79,"sourceCode":"\t\t\ts.result = cached\n\t\t\treturn\n\t\t}\n\t\tif errors.Is(err, catwalk.ErrNotModified) {\n\t\t\tslog.Info(\"Catwalk providers not modified\")\n\t\t\ts.result = cached\n\t\t\treturn\n\t\t}\n\t\tif err != nil {\n\t\t\t// Fall back to cached (which defaults to embedded if empty).\n\t\t\t// Being offline is routine and the fallback is sound, so this\n\t\t\t// is logged rather than reported to the caller.\n\t\t\tslog.Warn(\"Could not fetch providers from Catwalk\", \"error\", err)\n\t\t\ts.result = cached\n\t\t\treturn\n\t\t}\n\t\tif len(result) == 0 {\n\t\t\ts.result = cached\n\t\t\ts.err = errors.New(\"empty providers list from catwalk\")\n\t\t\treturn\n\t\t}\n\n\t\t// The catalog is usable from here on. A cache write failure only\n\t\t// costs the next run a refresh, so it is reported alongside a valid\n\t\t// result rather than in place of one.\n\t\ts.result = result\n\t\ts.err = s.cache.Store(result)\n\t})\n\treturn s.result, s.err\n}\n","sourceCodeStart":61,"sourceCodeEnd":91,"githubUrl":"https://github.com/charmbracelet/crush/blob/7944b8e52225d8805e31eacbf7ef24856b0dfb7a/internal/config/catwalk.go#L61-L91","documentation":"The catwalk-backed provider catalog fetcher sets this error when the remote catalog service returns a successful response containing zero providers. An empty catalog is treated as a broken response rather than a valid state: the fetcher keeps serving the previously cached catalog (s.result = cached) and stores this error so callers know the refresh failed while still having usable data.","triggerScenarios":"A refresh cycle where the Catwalk /providers endpoint returns an empty JSON array; transient server-side issues or a misconfigured/empty upstream catalog; network proxies stripping the body.","commonSituations":"Catwalk outage or partial degradation returning empty lists; corporate proxies intercepting responses; pointing a custom catalog URL at an endpoint that legitimately serves no providers.","solutions":["Retry later — cached providers keep working in the meantime; the next successful refresh clears the error.","Verify the configured Catwalk URL is correct and reachable (curl it and confirm a non-empty provider list).","Check proxy/firewall interference and any cached empty responses; force a refresh after fixing connectivity."],"exampleFix":"// before\nCRUSH_CATWALK_URL=https://wrong-mirror.example.com crush\n// after\nunset CRUSH_CATWALK_URL  # use the default catwalk endpoint\ncrush","handlingStrategy":"retry","validationCode":"// Sanity-check the catalog endpoint before startup\ncurl -fsS \"$CATWALK_URL/providers\" | jq 'length'  # must be > 0","typeGuard":null,"tryCatchPattern":"s.refresh(ctx)\nif s.err != nil && s.result != nil {\n    slog.Warn(\"Using cached providers after failed refresh\", \"error\", s.err) // degrade, don't abort\n}","preventionTips":["Point the catalog at the official Catwalk URL or a verified mirror that serves a non-empty list.","Rely on the built-in cache: an empty fetch degrades to cached providers rather than breaking startup.","Monitor proxy/firewall rules that could strip or replace API responses."],"tags":["network","providers","catalog","go"],"backgroundTag":"empty-catalog-response","analyzedSha":"7944b8e52225d8805e31eacbf7ef24856b0dfb7a","analyzedAt":"2026-08-29T12:48:59.079Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}