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

  1. Pass the markdown file explicitly: glow NOTES.md
  2. Rename or symlink your main doc to README.md (the first entry checked in readmeNames)
  3. If a README exists, verify it is readable (ls -l, cat) and matches one of the six accepted names exactly
  4. 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

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


AI-assisted analysis of charmbracelet/glow@e3970c813d (2026-08-15). Data as JSON: /api/errors/e94ff602636c4be0. Report an issue: GitHub.