chenhg5/cc-connect · error
fetch skill presets: %w
Error message
fetch skill presets: %w
What it means
The skill presets fetcher aggregates multiple remote sources; fetch throws "fetch skill presets: %w" only when every source failed AND there is no stale cached copy to fall back on. The wrapped error is the last/aggregate source failure. When a stale cache exists the caller only logs a warning and serves old data instead.
Source
Thrown at core/skill_presets.go:110
return c.data, nil
}
primaryURL := c.url
if primaryURL == "" {
primaryURL = defaultSkillPresetsURL
}
result, err := fetchSkillPresetsFromURL(primaryURL, skillPresetsHTTPTimeout)
if err != nil {
slog.Warn("primary skill presets fetch failed, trying fallback", "url", primaryURL, "error", err)
result, err = fetchSkillPresetsFromURL(fallbackSkillPresetsURL, skillPresetsFallbackHTTPTimeout)
}
if err != nil {
if c.data != nil {
slog.Warn("all skill presets sources failed, using stale cache", "error", err)
return c.data, nil
}
return nil, fmt.Errorf("fetch skill presets: %w", err)
}
c.data = result
c.fetchedAt = time.Now()
return c.data, nil
}
func fetchSkillPresetsFromURL(url string, timeout time.Duration) (*SkillPresetsResponse, error) {
slog.Debug("fetching skill presets", "url", url)
client := &http.Client{Timeout: timeout}
resp, err := client.Get(url)
if err != nil {
return nil, fmt.Errorf("HTTP GET %s: %w", url, err)
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("HTTP GET %s: status %d", url, resp.StatusCode)View on GitHub (pinned to 4000b2338a)
Solutions
- Restore network access (or proxy config) and retry the fetch
- Pre-seed the presets cache so a stale copy exists for offline fallback
- Check the wrapped error (%w) to see which source URL failed and why; fix or remove dead sources from the config
- Add the failing hosts to an allowlist if a firewall is blocking them
Example fix
// before
presets, err := fetchPresets(ctx)
// after
presets, err := fetchPresets(ctx)
if err != nil {
slog.Warn("skill presets unavailable, continuing with empty list", "err", err)
presets = &SkillPresetsResponse{}
} Defensive patterns
Strategy: fallback
Validate before calling
// before fetching, check a cached copy exists to fall back on
if cache := readPresetsCache(); cache != nil {
slog.Info("skill presets: using cached copy", "fetched_at", cacheTime)
} Type guard
func hasStaleCache(c *presetsCache) bool {
c.mu.Lock(); defer c.mu.Unlock()
return c.data != nil
} Try / catch
presets, err := fetchPresets(ctx)
if err != nil {
var netErr net.Error
if errors.As(err, &netErr) || strings.Contains(err.Error(), "fetch skill presets") {
slog.Warn("skill presets unavailable offline; using empty list", "err", err)
presets = &core.SkillPresetsResponse{}
}
} Prevention
- Pre-populate the presets cache on first install so offline starts have a fallback
- Configure multiple preset source URLs so one failure doesn't empty the list
- Monitor the wrapped cause: repeated all-sources-failed indicates DNS/firewall issues, not flakiness
When it happens
Trigger: Calling the skill presets listing (e.g. the /skills preset UI) while offline, when all preset source URLs are unreachable, and the local cache file has never been populated (first run) or was cleared.
Common situations: First launch on an air-gapped/CI machine with no network; DNS failure on the host; preset CDN temporarily down shortly after a fresh install with no cache yet.
Related errors
- fetch presets: %w
- range chunk retries exhausted
- request usage endpoint: %w
- reasonix: POST %s: %w
- init failed: %w
AI-assisted analysis of chenhg5/cc-connect@4000b2338a (2026-09-06).
Data as JSON: /api/errors/8c8e41dc96fdde53.
Report an issue: GitHub.