{"record":{"id":"5c25604dd9041a90","repo":"kovidgoyal/kitty","slug":"the-font-specification-s-is-invalid-as-s-does-no","errorCode":null,"errorMessage":"The font specification %s is invalid as %s does not contain an =","messagePattern":"The font specification (.+?) is invalid as (.+?) does not contain an =","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"kittens/choose_fonts/types.go","lineNumber":300,"sourceCode":"}\n\nfunc NewFontSpec(spec string, features map[string]FeatureData) (ans FontSpec, err error) {\n\tif spec == \"\" || spec == \"auto\" {\n\t\tans.system = settable_string{\"auto\", true}\n\t\treturn\n\t}\n\tparts, err := shlex.Split(spec)\n\tif err != nil {\n\t\treturn\n\t}\n\tif !strings.Contains(parts[0], \"=\") {\n\t\tans.system = settable_string{spec, true}\n\t\treturn\n\t}\n\tfor _, item := range parts {\n\t\tk, v, found := strings.Cut(item, \"=\")\n\t\tif !found {\n\t\t\treturn ans, fmt.Errorf(\"The font specification %s is invalid as %s does not contain an =\", spec, item)\n\t\t}\n\t\tswitch k {\n\t\tcase \"family\":\n\t\t\tans.family = settable_string{v, true}\n\t\tcase \"style\":\n\t\t\tans.style = settable_string{v, true}\n\t\tcase \"full_name\":\n\t\t\tans.full_name = settable_string{v, true}\n\t\tcase \"postscript_name\":\n\t\t\tans.postscript_name = settable_string{v, true}\n\t\tcase \"variable_name\":\n\t\t\tans.variable_name = settable_string{v, true}\n\t\tcase \"features\":\n\t\t\tfor _, x := range utils.NewSeparatorScanner(v, \" \").Split(v) {\n\t\t\t\tpff, err := NewParsedFontFeature(x, features)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn ans, err\n\t\t\t\t}","sourceCodeStart":282,"sourceCodeEnd":318,"githubUrl":"https://github.com/kovidgoyal/kitty/blob/6d5d0c440603ad9bdf6dcd599f73f6dde21acb44/kittens/choose_fonts/types.go#L282-L318","documentation":"The choose_fonts kitten parses a font specification string (e.g. 'family=Mono style=Bold') by splitting it into items and cutting each on '='. If an item has no '=' separator, the specification is rejected. This is a config-parsing error for user-supplied font strings.","triggerScenarios":"Calling the font specification parser with a spec like 'Mono' or 'Mono Bold' where an item lacks key=value form; passing a malformed --font-spec / font family string to the choose_fonts kitten.","commonSituations":"Typing a bare font family name instead of 'family=Name', forgetting the '=' in 'style=Bold', extra spaces producing items like 'Bold' without a key.","solutions":["Rewrite the spec as key=value pairs, e.g. 'family=JetBrains Mono style=Bold'","Quote the whole spec so the shell doesn't split it into stray items","Check for stray commas/spaces that create standalone tokens without '='"],"exampleFix":"// before\nspec := \"JetBrains Mono\"\n// after\nspec := \"family=JetBrains Mono\"","handlingStrategy":"validation","validationCode":"func validFontSpec(spec string) bool {\n\tfor _, item := range strings.Fields(spec) {\n\t\tif _, _, ok := strings.Cut(item, \"=\"); !ok {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}","typeGuard":null,"tryCatchPattern":"if err := parseFontSpec(spec); err != nil { log.Printf(\"bad font spec %q: %v\", spec, err) }","preventionTips":["Always use key=value pairs (family=, style=, size=) in font specs","Shell-quote the entire spec so spaces don't split items"],"tags":["kitty","fonts","config-parsing","choose-fonts"],"backgroundTag":"invalid-config-value","analyzedSha":"6d5d0c440603ad9bdf6dcd599f73f6dde21acb44","analyzedAt":"2026-08-27T14:20:20.142Z","schemaVersion":2},"datasetVersion":"2026-08-27T19:17:21.184Z"}