kovidgoyal/kitty · warning

Ignoring invalid font_features {val}

Error message

Ignoring invalid font_features {val}

What it means

A font_features line must be 'font_features <family> <feature...>' with at least two tokens. With fewer than 2 parts (or only 'none' being special), kitty logs this and ignores the whole line.

Source

Thrown at kitty/options/utils.py:1076

    ans = to_bool(val)
    if ans and dict_with_parse_results is not None:
        dict_with_parse_results['mouse_map'] = [None]
    return ans


def clear_all_shortcuts(val: str, dict_with_parse_results: dict[str, Any] | None = None) -> bool:
    ans = to_bool(val)
    if ans and dict_with_parse_results is not None:
        dict_with_parse_results['map'] = [None]
    return ans


def font_features(val: str) -> Iterable[tuple[str, tuple[defines.ParsedFontFeature, ...]]]:
    if val == 'none':
        return
    parts = val.split()
    if len(parts) < 2:
        log_error(f'Ignoring invalid font_features {val}')
        return
    if parts[0]:
        features = []
        for feat in parts[1:]:
            try:
                features.append(defines.ParsedFontFeature(feat))
            except ValueError:
                log_error(f'Ignoring invalid font feature: {feat}')
        yield parts[0], tuple(features)


def modify_font(val: str) -> Iterable[tuple[str, FontModification]]:
    parts = val.split()
    pos, plen = 0, len(parts)
    if plen < 2:
        log_error(f'Ignoring invalid modify_font: {val}')
        return
    mtype: ModificationType | None = getattr(ModificationType, parts[pos], None)

View on GitHub (pinned to 6d5d0c4406)

Solutions

  1. Add the font family as the first token: font_features <family> <features...>.
  2. Example: font_features FiraCode +ss01 +zero
  3. Use 'font_features none' to disable.

Example fix

# before
font_features +ss01

# after
font_features FiraCode +ss01
Defensive patterns

Strategy: validation

Validate before calling

def valid_font_features(val: str) -> bool:
    if val == 'none':
        return True
    parts = val.split()
    return len(parts) >= 2

Type guard

def is_font_features_shaped(val: str) -> bool:
    p = val.split()
    return val == 'none' or len(p) >= 2

Prevention

When it happens

Trigger: font_features with a single token, e.g. 'font_features +ss01' missing the font family prefix, or an empty-ish value other than 'none'.

Common situations: Forgetting the font family argument; assuming features apply globally without specifying a family; using 'font_features none' correctly (no error) vs malformed lists.

Related errors


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