charmbracelet/glow · error
missing markdown source
Error message
missing markdown source
What it means
When its argument is a directory (or empty, defaulting to "."), glow walks the tree via filepath.Walk looking for a base name equal (case-insensitively) to one of readmeNames: README.md, README, Readme.md, Readme, readme.md, readme. If no file with one of those exact names is readable, src stays nil and this error is returned. Note it matches only those six names, not *.md in general.
Source
Thrown at main.go:138
if err != nil {
continue
}
u, _ := filepath.Abs(path)
src = &source{r, u}
// abort filepath.Walk
return errors.New("source found")
}
}
return nil
})
if src != nil {
return src, nil
}
return nil, errors.New("missing markdown source")
}
r, err := os.Open(arg)
if err != nil {
return nil, fmt.Errorf("unable to open file: %w", err)
}
u, err := filepath.Abs(arg)
if err != nil {
return nil, fmt.Errorf("unable to get absolute path: %w", err)
}
return &source{r, u}, nil
}
// validateStyle checks if the style is a default style, if not, checks that
// the custom style exists.
func validateStyle(style string) error {
if style != "auto" && styles.DefaultStyles[style] == nil {
style = utils.ExpandPath(style)View on GitHub (pinned to e3970c813d)
Solutions
- Pass the markdown file explicitly: glow NOTES.md
- Rename or symlink your main doc to README.md (the first entry checked in readmeNames)
- If a README exists, verify it is readable (ls -l, cat) and matches one of the six accepted names exactly
- Run glow from the directory that actually contains the README
Example fix
# before: docs/ contains only index.md glow docs/ # after: point glow at the file glow docs/index.md # or: mv docs/index.md docs/README.md && glow docs/
Defensive patterns
Strategy: validation
Validate before calling
var readmeNames = []string{"README.md", "README", "Readme.md", "Readme", "readme.md", "readme"}
func hasReadableReadme(dir string) bool {
found := false
_ = filepath.Walk(dir, func(p string, info os.FileInfo, err error) error {
if err != nil || info.IsDir() {
return nil
}
for _, n := range readmeNames {
if strings.EqualFold(filepath.Base(p), n) {
found = true
return filepath.SkipAll
}
}
return nil
})
return found
}
if !hasReadableReadme(dir) {
// pass the explicit file instead of the directory
arg = filepath.Join(dir, "index.md")
} Try / catch
src, err := openSource(arg)
if err != nil {
if err.Error() == "missing markdown source" {
// directory had no README-named file; pick a specific markdown file
return openSource(filepath.Join(arg, "index.md"))
}
return err
} Prevention
- In scripts, always pass an explicit file path rather than relying on directory discovery
- Name your entry document README.md — the first pattern glow checks
- Remember the accepted set is exactly six names; README.markdown and *.md in general do not match
When it happens
Trigger: Running glow (or glow with a directory argument) in a tree containing index.md, NOTES.md, README.markdown, or ReadMe.md — none of which are in the list; a README that exists but fails os.Open on every candidate due to permissions (the walk continues, src stays nil); passing a path to an empty or wrong directory.
Common situations: Running glow inside docs/ or a notes folder that has no README; repos using the older README.markdown convention; mixed-case variants like ReadMe.md; file permissions (chmod 000) on the README under a root-owned directory.
Related errors
- can't find README in GitHub repository
- can't find README in GitLab repository
- cannot use both pager and tui
- unable to set config file: %w
- could not write configuration file: %w
AI-assisted analysis of charmbracelet/glow@e3970c813d (2026-08-15).
Data as JSON: /api/errors/e94ff602636c4be0.
Report an issue: GitHub.