kovidgoyal/kitty · error
Unknown configuration key: %#v
Error message
Unknown configuration key: %#v
What it means
Generated into the Go Config.Parse method: when a config line's key doesn't match any known option (the switch falls through to default), the parser rejects it with 'Unknown configuration key'. This is the strict-key behavior for Go-embedded kitty config parsers used by kittens.
Source
Thrown at kitty/conf/generate.py:696
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:
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) }')View on GitHub (pinned to 6d5d0c4406)
Solutions
- Fix the typo — compare the key against kitty's documented option list
- Comment out or remove the unknown key
- Regenerate/upgrade to a kitty version whose generated Go parser knows the key
- If the key is intentionally Python-only, move it out of files consumed by the Go parser
Example fix
# before font_familly = Fira Code # after font_family = Fira Code
Defensive patterns
Strategy: validation
Validate before calling
knownKeys := map[string]bool{ /* generated from schema */ }
if !knownKeys[key] {
return fmt.Errorf("skipping unknown key %q", key)
} Type guard
func isKnownKey(key string, known map[string]bool) bool { return known[key] } Try / catch
if err := cfg.Parse(key, val); err != nil {
if strings.Contains(err.Error(), "Unknown configuration key") {
log.Printf("warning: ignoring unknown key %q", key)
continue
}
return err
} Prevention
- Spell-check option names against kitty docs
- Run kitty --debug-config to surface unknown keys early
- Regenerate/upgrade parsers when adopting new options
When it happens
Trigger: Passing an unrecognized key in a config file parsed by the generated Go parser, via kitty -o bogus_key=value, or a remote control payload — e.g. a typo like 'font_familly' or an option only supported in the Python config layer, not the generated Go parser.
Common situations: Typos in option names; configs written for a newer kitty version than the Go parser was generated from; options that exist in kitty.conf but aren't part of the Go schema for a specific kitten; leftover deprecated keys after upgrades.
Related errors
- unrecognized key in video_preview: %s
- %#v is not a valid value for %s. Valid values are: %s
- Failed to parse %s = %#v with error: %w
- This should be run as kitten broadcast
- No option named: {k}
AI-assisted analysis of kovidgoyal/kitty@6d5d0c4406 (2026-08-27).
Data as JSON: /api/errors/435f26e395b95784.
Report an issue: GitHub.