kovidgoyal/kitty · error
Too many nested include directives while processing config…
Error message
Too many nested include directives while processing config file: %s
What it means
The config file parser limits include directives to 32 levels of nesting to prevent infinite recursion. When parsing an include chain deeper than 32 files, it aborts with this error naming the file being processed.
Solutions
- Check the named file and trace its include chain for a cycle
- Flatten the include hierarchy by inlining deeply nested includes
- Use the AllIncludedFiles set / logs to identify which files form the loop and break it
Example fix
# before # a.conf include b.conf # b.conf include a.conf # after # a.conf include b.conf # b.conf map ctrl+a>1 load_config_file
Defensive patterns
Strategy: validation
Validate before calling
seen := map[string]bool{}
var check func(path string, depth int) error
check = func(path string, depth int) error {
if depth > 32 { return fmt.Errorf("include chain too deep at %s", path) }
if seen[path] { return fmt.Errorf("circular include at %s", path) }
seen[path] = true
return nil // recurse into included files similarly
} Prevention
- Lint configs for include cycles before deployment
- Keep include graphs shallow; prefer one level of shared snippets
When it happens
Trigger: A chain of config files where each includes the next (directly or cyclically) exceeding depth 32, e.g. a.conf includes b.conf includes c.conf ... or two files that include each other.
Common situations: Circular includes (file A includes B which includes A), or over-modularized configs where shared snippets include other snippets repeatedly.
Related errors
- Could not find included config file
- Could not read from included config file
- Empty include paths not allowed
- is unknown for clear_terminal, using reset
- allow_fallback values must be a subset of shifted, ascii…
AI-assisted analysis of kovidgoyal/kitty@6d5d0c4406 (2026-08-27).
Data as JSON: /api/errors/b86ad02e28c4e8e8.
Report an issue: GitHub.
Appendix: source
Thrown at tools/config/api.go:128
}
return os.Getenv(k)
})
}
const OverridesFileName = "<overrides>"
func (self *ConfigParser) parse(scanner Scanner, name, base_path_for_includes string, depth int) error {
if self.seen_includes[name] { // avoid include loops
return nil
}
self.seen_includes[name] = true
if self.AllIncludedFiles != nil && name != OverridesFileName {
self.AllIncludedFiles.Add(name)
}
recurse := func(r io.Reader, nname, base_path_for_includes string) error {
if depth > 32 {
return fmt.Errorf("Too many nested include directives while processing config file: %s", name)
}
escanner := bufio.NewScanner(r)
return self.parse(escanner, nname, base_path_for_includes, depth+1)
}
make_absolute := func(path string) (string, error) {
if path == "" {
return "", fmt.Errorf("Empty include paths not allowed")
}
if !filepath.IsAbs(path) {
path = filepath.Join(base_path_for_includes, path)
}
return path, nil
}
lnum := 0
next_line_num := 0
next_line := ""View on GitHub (pinned to 6d5d0c4406)