kovidgoyal/kitty · error
Unknown change type: %#v
Error message
Unknown change type: %#v
What it means
While rendering directory-diff entries, render.go dispatches on each changed item's type string; any value other than the recognized kinds (e.g. 'add', 'remove', 'change', 'rename') reaches the default branch and raises this error with the %#v-formatted type. It indicates the collection of changes contains an entry type the renderer does not know.
Source
Thrown at kittens/diff/render.go:874
if is_binary {
if is_img {
ans, err = image_lines(path, "", screen_size, margin_size, image_size, ans)
} else {
ans, err = binary_lines(path, "", columns, margin_size, ans)
}
} else {
ans, err = all_lines(path, columns, margin_size, false, ans)
}
if err != nil {
return err
}
case "rename":
ans, err = rename_lines(path, changed_path, columns, margin_size, ans)
if err != nil {
return err
}
default:
return fmt.Errorf("Unknown change type: %#v", item_type)
}
return nil
})
var ll []*LogicalLine
if len(ans) > 1 {
ll = ans[:len(ans)-1]
} else {
// Having am empty list of lines causes panics later on
ll = []*LogicalLine{{line_type: EMPTY_LINE, screen_lines: []*ScreenLine{{}}}}
}
return &LogicalLines{lines: ll, title_line_indices: title_line_indices, margin_size: margin_size, columns: columns}, err
}
View on GitHub (pinned to 6d5d0c4406)
Solutions
- Identify the offending item type from the %#v value in the message.
- If it comes from git metadata, refresh/regenerate the change list (git status) and retry; typechange entries can be normalized to remove+add.
- Update kitty to the latest version in case the type is newly supported.
- If calling render() directly, map your change types onto the supported set before rendering.
Example fix
// before
collection.Add("copy", oldPath, newPath)
// after
collection.Add("add", "", newPath)
collection.Add("remove", oldPath, "") Defensive patterns
Strategy: type-guard
Validate before calling
// Go: whitelist change types before handing a collection to render()
allowed := map[string]bool{"add": true, "remove": true, "change": true, "rename": true}
for _, it := range collection.Items {
if !allowed[it.Type] {
return fmt.Errorf("unsupported change type %q; map it to add/remove", it.Type)
}
} Type guard
func isSupportedChangeType(t string) bool {
switch t {
case "add", "remove", "change", "rename":
return true
}
return false
} Try / catch
On 'Unknown change type', extract the %#v value from the message, normalize the entry (e.g. copy/typechange -> remove+add), and re-render; log unhandled values for upstream reporting.
Prevention
- Map external VCS status codes onto the supported type set before rendering.
- Regenerate git status data if it may be stale or corrupt.
- Keep kitty updated so newly supported types render natively.
When it happens
Trigger: A change collection (typically produced from git status parsing or similar) containing an unexpected type string such as 'copy', 'typechange', or an empty/garbage value; extension or newer kitty versions producing types this build's renderer can't handle; custom code feeding render() its own collection.
Common situations: Version skew between components generating the change list and the renderer; git reporting 'T' (typechange) or 'C' (copy) entries that fall outside the handled set; third-party tools reusing the kitten's render API with richer type vocabularies.
Related errors
- The value {val} is not a valid choice for undercurl_style
- Invalid box_drawing scale, must have four entries
- You must specify exactly two files/directories to compare
- The items to be diffed should both be either directories or
- This terminal does not support the kitty keyboard protocol,
AI-assisted analysis of kovidgoyal/kitty@6d5d0c4406 (2026-08-27).
Data as JSON: /api/errors/de05ccae92fd51f0.
Report an issue: GitHub.