kovidgoyal/kitty · warning · ErrNoCacheFound

No cache found and max cache age is negative

Error message

No cache found and max cache age is negative

What it means

ErrNoCacheFound is a sentinel error in tools/themes/collection.go returned by the cached-theme paths (fetch_cached, change_colors, GetThemeNames) when no local theme cache exists AND the configured max cache age is negative — i.e. the caller forbade network fetches (cache-only mode) but there is nothing cached yet. It distinguishes 'allowed to download' from 'must use cache, cache missing'.

Source

Thrown at tools/themes/collection.go:333

	"selection_background":                 true,
	"selection_foreground":                 true,
	"tab_bar_background":                   true,
	"tab_bar_margin_color":                 true,
	"url_color":                            true,
	"visual_bell_color":                    true,
	"wayland_titlebar_color":               true,
	"window_title_bar_active_background":   true,
	"window_title_bar_active_foreground":   true,
	"window_title_bar_inactive_background": true,
	"window_title_bar_inactive_foreground": true, // ALL_COLORS_END
} // }}}

type JSONMetadata struct {
	Etag      string `json:"etag"`
	Timestamp string `json:"timestamp"`
}

var ErrNoCacheFound = errors.New("No cache found and max cache age is negative")

func set_comment_in_zip_file(path string, comment string) error {
	src, err := zip.OpenReader(path)
	if err != nil {
		return err
	}
	defer src.Close()
	buf := bytes.Buffer{}
	dest := zip.NewWriter(&buf)
	if err = dest.SetComment(comment); err != nil {
		return err
	}
	for _, sf := range src.File {
		err = dest.Copy(sf)
		if err != nil {
			return err
		}
	}

View on GitHub (pinned to 6d5d0c4406)

Solutions

  1. Allow the initial download once: run with a non-negative max cache age so the cache is populated, after which cache-only mode works
  2. If offline, copy a prebuilt cache from another machine into the kitty themes cache directory (~/.cache/kitty/themes)
  3. Check for this sentinel with errors.Is(err, themes.ErrNoCacheFound) and show a friendly 'run once online' message

Example fix

# before
kitten themes --cache-age=-1   # error: No cache found and max cache age is negative

# after
kitten themes                  # once, online: populates the cache
kitten themes --cache-age=-1   # now works offline
Defensive patterns

Strategy: fallback

Validate before calling

import os

cache_exists = os.path.exists(os.path.expanduser('~/.cache/kitty/themes'))
cache_only = max_cache_age < 0
if cache_only and not cache_exists:
    # populate cache once with a network-allowed call before proceeding
    ...

Type guard

func isNoCache(err error) bool {
    return errors.Is(err, themes.ErrNoCacheFound)
}

Try / catch

if err := fetch_cached(...); err != nil {
    if errors.Is(err, themes.ErrNoCacheFound) {
        // prompt user to run once online, or use bundled defaults
    }
}

Prevention

When it happens

Trigger: Invoking theme operations (e.g. `kitten themes` in --cache-only mode, or the API's GetThemeNames/fetch_cached) with a negative max cache age (cache age < 0 means 'never hit the network') before any theme cache has been downloaded.

Common situations: First run of the themes kitten with network disabled/cache-only requested; CI or offline machines; deleting ~/.cache/kitty/themes then running in cache-only mode; misinterpreting the max-age API where a negative value means 'no network'.

Related errors


AI-assisted analysis of kovidgoyal/kitty@6d5d0c4406 (2026-08-27). Data as JSON: /api/errors/9717142b4cff55a0. Report an issue: GitHub.