cayleygraph/cayley · error
could not write history to %q: %v
Error message
could not write history to %q: %v
What it means
This error is returned by the persist function in internal/repl/repl.go when the liner terminal fails to write the accumulated readline history to the history file on disk. The history file was opened successfully (OS-level open succeeded), but term.WriteHistory(f) failed while serializing or writing the history entries. It wraps the underlying liner error with the file path for context.
Source
Thrown at internal/repl/repl.go:280
f, err := os.Open(path)
if err != nil {
return term, err
}
defer f.Close()
_, err = term.ReadHistory(f)
return term, err
}
func persist(term *liner.State, path string) error {
f, err := os.OpenFile(path, os.O_RDWR|os.O_APPEND|os.O_CREATE, 0666)
if err != nil {
return fmt.Errorf("could not open %q to append history: %v", path, err)
}
defer f.Close()
_, err = term.WriteHistory(f)
if err != nil {
return fmt.Errorf("could not write history to %q: %v", path, err)
}
return term.Close()
}
View on GitHub (pinned to 81dcd7d73e)
Solutions
- Check the wrapped %v error for the underlying cause (ENOSPC, EIO, EBADF) and free disk space or fix the filesystem
- Verify the history file path is on a writable, available filesystem
- Check that no other process holds a conflicting lock on the history file
- Retry persisting, or fall back to skipping history persistence so the REPL still exits cleanly
Example fix
// before
_, err = term.WriteHistory(f)
if err != nil {
return fmt.Errorf("could not write history to %q: %v", path, err)
}
// after
_, err = term.WriteHistory(f)
if err != nil {
log.Printf("warning: history not saved to %q: %v", path, err)
return nil // don't fail REPL shutdown over history persistence
} Defensive patterns
Strategy: try-catch
Validate before calling
f, err := os.OpenFile(path, os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0666)
if err != nil { return err }
f.Close()
// disk space check (unix)
// syscall.Statfs(path, &st); if st.Bavail*uint64(st.Bsize) < minFree { ... } Try / catch
if err := persist(term, historyPath); err != nil {
if strings.Contains(err.Error(), "could not write history") {
log.Printf("history not saved: %v", err) // degrade gracefully
} else {
return err
}
} Prevention
- Keep the history file on local writable storage, not network mounts
- Check available disk space before long REPL sessions
- Don't close the liner term before persist runs
- Treat history persistence as best-effort and never let it block shutdown
When it happens
Trigger: Calling persist(term, path) where os.OpenFile succeeded but liner's WriteHistory fails — e.g. the file descriptor becomes invalid mid-write, the disk fills up, or the liner state is corrupted/closed before the write. It is invoked during REPL shutdown/cleanup paths from Repl and an anonymous cleanup goroutine.
Common situations: Disk-full or quota-exceeded while exiting a REPL session; history file on a network mount that dropped; another process truncating or locking the history file concurrently; file system became read-only after open.
Understand the failure class
Background: "failed to write file", "Could not save figure", "Error saving remote file" — file write failed: causes and fixes across languages and libraries — this error's family across 38 libraries.
Related errors
- could not open %q to append history: %v
- ErrParseMore
- could not open file %q: %v
- unsupported query language: %q
AI-assisted analysis of cayleygraph/cayley@81dcd7d73e (2026-09-06).
Data as JSON: /api/errors/d92924be29b6a141.
Report an issue: GitHub.