kovidgoyal/kitty · error

Failed to parse %s = %#v with error: %w

Error message

Failed to parse %s = %#v with error: %w

What it means

Generated Go code for each known config option: the option key was recognized, but its value failed the option's type-specific parser (e.g. an integer parser receiving text, a color parser receiving an invalid color, a bool parser receiving 'yesn'). The wrapping error adds context (option name and raw value) to the underlying parse failure.

Source

Thrown at kitty/conf/generate.py:706

        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:
                a(f'c.{oname} = append(c.{oname}, temp_val...)')
            else:
                a(f'c.{oname} = temp_val')
        if keyboard_shortcuts:
            a('case "map":')
            a('tempsc, err := config.ParseMap(val)')
            a('if err != nil { return fmt.Errorf("Failed to parse map = %#v with error: %w", val, err) }')
            a('c.KeyboardShortcuts = append(c.KeyboardShortcuts, tempsc)')
        a('}')
        a('return}')
    else:
        a('return fmt.Errorf("Unknown configuration key: %#v", key)')
        a('}')
    return '\n'.join(lines)


def main() -> None:

View on GitHub (pinned to 6d5d0c4406)

Solutions

  1. Check the inner error (%w) — it states what the value couldn't be parsed as; fix the value's format/type
  2. Look up the option in kitty docs for its expected value syntax
  3. Quote strings containing special characters; use documented units/booleans (yes/no/true/false)
  4. Upgrade kitty if the value format is valid in a newer generated parser

Example fix

# before
scrollback_lines = unlimited-ish
foreground = bluish

# after
scrollback_lines = 10000
foreground = #c0c0ff
Defensive patterns

Strategy: try-catch

Validate before calling

// validate common types before parse
if key == "scrollback_lines" {
    if _, err := strconv.Atoi(val); err != nil {
        return fmt.Errorf("%s must be an integer", key)
    }
}

Type guard

func isInt(s string) bool { _, err := strconv.Atoi(s); return err == nil }

Try / catch

if err := cfg.Parse(key, val); err != nil {
    if strings.Contains(err.Error(), "Failed to parse") {
        log.Printf("bad value for %s, using default", key)
        continue
    }
    return err
}

Prevention

When it happens

Trigger: A recognized kitty option whose value doesn't parse: scrollback_lines = lots, foreground = notacolor, remember_window_size = 42 — hit via kitty.conf, -o flags, or remote control when processed by a Go-embedded config parser.

Common situations: Unit mismatches or typos in values; copy-pasting configs across kitty versions where value syntax changed; locale differences (comma vs dot in numbers); feeding Python-syntax values to Go parsers.

Understand the failure class

Related errors


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