kovidgoyal/kitty · error

%#v is not a valid value for

Error message

%#v is not a valid value for %s. Valid values are: %s

What it means

This error is generated (by kitty's config-code generator, generate.py) into the Go parser for every option with a fixed set of valid values (a choices option). At runtime, when a config file or remote-control command supplies a value not in the option's list of allowed choices, the generated switch's default branch returns this error naming the value, the option, and the valid values.

Solutions

  1. Read the error message: it lists every valid value — correct the value in kitty.conf or the -o argument to one of them
  2. Check kitty docs for the option to confirm supported values in your installed version
  3. Upgrade kitty if the value is valid in a newer release (the generated parser lags behind)
  4. Remove the line to fall back to the default if you don't need the setting

Example fix

# before
background_opacity_layout = block
color_strategy = maybe

# after
background_opacity_layout = block
# use only values listed in the error, e.g.:
sync_strategy = resize
Defensive patterns

Strategy: validation

Validate before calling

valid := map[string]map[string]bool{ /* from generated schema */
  "background_opacity_strategy": {"block": true, "single": true},
}
if opts, ok := valid[key]; ok && !opts[val] {
    return fmt.Errorf("invalid value %q for %s; allowed: %v", val, key, opts)
}

Type guard

func isValidChoice(key, val string, schema map[string][]string) bool {
    for _, c := range schema[key] {
        if c == val {
            return true
        }
    }
    return false
}

Try / catch

if err := cfg.Parse(key, val); err != nil {
    if strings.Contains(err.Error(), "is not a valid value for") {
        warnAndUseDefault(key, val)
    } else {
        return err
    }
}

Prevention

When it happens

Trigger: Setting a choices-typed kitty option to an invalid string in kitty.conf (e.g. background_opacity = maybe), passing it via kitty -o key=value, or sending it over the remote control protocol to a Go-based parser (kitten like icat/transfer that embeds the config parser).

Common situations: Typos in kitty.conf values; using an option value from a newer/older kitty version than the parser was generated from; copy-pasted configs from tutorials with deprecated values (e.g. old font styles or deprecated strategies).

Related errors


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

Appendix: source

Thrown at kitty/conf/generate.py:689

        for i, c in enumerate(choice_vals):
            c = cval(c)
            if i == 0:
                a(f'{oname}_{c} {oname}_Choice_Type = iota')
            else:
                a(f'{oname}_{c}')
        a(')')
        a(f'func (x {oname}_Choice_Type) String() string {{')
        a('switch x {')
        a('default: return ""')
        for c in choice_vals:
            a(f'case {oname}_{cval(c)}: return "{c}"')
        a('}}')
        a(f'func {go_parsers[oname].split("(")[0]}(val string) (ans {go_types[oname]}, err error) {{')
        a('switch val {')
        for c in choice_vals:
            a(f'case "{c}": return {oname}_{cval(c)}, nil')
        vals = ', '.join(choice_vals)
        a(f'default: return ans, fmt.Errorf("%#v is not a valid value for %s. Valid values are: %s", val, "{c}", "{vals}")')
        a('}}')

    has_parsers = bool(go_parsers or keyboard_shortcuts)
    a('func (c *Config) Parse(key, val string) (err error) {')
    if has_parsers:
        a('switch key {')
        a('default: return fmt.Errorf("Unknown configuration key: %#v", key)')
        for oname, pname in go_parsers.items():
            ol = oname.lower()
            is_multiple = oname in multiopts
            a(f'case "{ol}":')
            if is_multiple:
                a(f'var temp_val []{go_types[oname]}')
            else:
                a(f'var temp_val {go_types[oname]}')
            a(f'temp_val, err = {pname}')
            a(f'if err != nil {{ return fmt.Errorf("Failed to parse {ol} = %#v with error: %w", val, err) }}')
            if is_multiple:

View on GitHub (pinned to 6d5d0c4406)