charmbracelet/glow · error · errMsg
could not load file: missing path
Error message
could not load file: missing path
What it means
loadLocalMarkdown is a bubbletea Cmd used by the stash/pager to read a document from disk into md.Body. If the markdown struct's localPath is the empty string, there is nothing to os.ReadFile, so it immediately returns this errMsg. Documents that come from the network or are constructed without a path have localPath == "".
Source
Thrown at ui/stash.go:844
if itemsOnPage < m.paginator().PerPage {
n := (m.paginator().PerPage - itemsOnPage) * stashViewItemHeight
if len(mds) == 0 {
n -= stashViewItemHeight - 1
}
for i := 0; i < n; i++ {
fmt.Fprint(&b, "\n")
}
}
return b.String()
}
// COMMANDS
func loadLocalMarkdown(md *markdown) tea.Cmd {
return func() tea.Msg {
if md.localPath == "" {
return errMsg{errors.New("could not load file: missing path")}
}
data, err := os.ReadFile(md.localPath)
if err != nil {
log.Debug("error reading local file", "error", err)
return errMsg{err}
}
md.Body = string(data)
return fetchedMarkdownMsg(md)
}
}
func filterMarkdowns(m stashModel) tea.Cmd {
return func() tea.Msg {
if m.filterInput.Value() == "" || !m.filterApplied() {
return filteredMarkdownMsg(m.markdowns) // return everything
}
View on GitHub (pinned to e3970c813d)
Solutions
- Open the document from the local filesystem (file picker or glow <path>) so localPath is populated
- For remote/stashed docs, use the fetch-from-stash command path instead of the local loader
- If embedding glow's UI, always construct markdown with a non-empty localPath before triggering a reload
Example fix
// ui/ui.go — local documents get a path
md := &markdown{localPath: path}
// before (path missing)
md := &markdown{}
cmd := loadLocalMarkdown(md) // errMsg: could not load file: missing path
// after
md := &markdown{localPath: "/tmp/errlookup-LwPSGd/README.md"}
cmd := loadLocalMarkdown(md) Defensive patterns
Strategy: type-guard
Validate before calling
// before issuing loadLocalMarkdown, make sure a path exists
if md.localPath == "" {
md.localPath = pickFileWithPicker() // or refuse the action
if md.localPath == "" {
return nil // do not dispatch the load command at all
}
} Type guard
// hasLocalSource reports whether md can be loaded from disk
// (ui/markdown.go keeps the path in the unexported localPath field).
func hasLocalSource(md *markdown) bool {
return md != nil && md.localPath != ""
}
if !hasLocalSource(md) {
return tea.Quit // or route to the network fetch command instead
}
cmd := loadLocalMarkdown(md) Try / catch
// errMsg arrives as a tea.Msg in Update:
switch msg := msg.(type) {
case errMsg:
if strings.Contains(msg.err.Error(), "missing path") {
// document has no backing file; refresh state or switch source
return m, fetchFromStashCmd(m.currentDocument)
}
m.err = msg
return m, tea.Quit
} Prevention
- Always populate localPath when constructing markdown values that will be reloaded (as ui/ui.go:152 does for local files)
- Treat empty localPath as 'remote-only document' and dispatch the stash/network fetch command instead
- Do not wire file-watch reloads to documents you did not open from disk
When it happens
Trigger: Opening a markdown item in the TUI whose localPath was never set (e.g., a news/stash item fetched from the network rather than a local file); a document struct built with only a URL; triggering a reload (pager key or file-watch event) after the path field was lost.
Common situations: Using the stash UI on remote/Glow-hosted docs and hitting the local-load path; opening the pager on a doc created from stdin where no filename exists; stale state after a failed load.
Related errors
- unable to run tui program: %w
- error parsing config: %v
- error creating glamour renderer: %w
- error rendering markdown: %w
AI-assisted analysis of charmbracelet/glow@e3970c813d (2026-08-15).
Data as JSON: /api/errors/ca6aa3a2e1ee4b13.
Report an issue: GitHub.