cayleygraph/cayley · warning
could not open %q to append history: %v
Error message
could not open %q to append history: %v
What it means
This error is returned by the REPL's persist helper when it cannot open the history file for appending. os.OpenFile with O_RDWR|O_APPEND|O_CREATE failed — typically due to filesystem permissions, a missing parent directory, or the path being a directory. The REPL then reports the path and the underlying OS error so history cannot be saved.
Source
Thrown at internal/repl/repl.go:275
os.Exit(1)
}
os.Exit(0)
}()
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 underlying OS error (%v) — fix permissions with chmod/chown on the file or its parent directory.
- Create the parent directory of the history file before starting the REPL (mkdir -p).
- Pass a writable file path via the history flag/option, e.g. --history /tmp/cayley_history.
- If HOME is unset in the environment, set HOME to a writable directory or give an explicit history path.
Example fix
// before cayley repl --history ~/nonexistent-dir/history // after mkdir -p ~/cayley && cayley repl --history ~/cayley/history
Defensive patterns
Strategy: try-catch
Validate before calling
dir := filepath.Dir(historyPath)
if _, err := os.Stat(dir); os.IsNotExist(err) {
os.MkdirAll(dir, 0o755)
}
if f, err := os.OpenFile(historyPath, os.O_RDWR|os.O_APPEND|os.O_CREATE, 0o666); err != nil {
return err
} else {
f.Close()
}
Try / catch
if err := repl.Repl(ctx, h, lang, timeout); err != nil {
var pe *fs.PathError
if errors.As(err, &pe) {
log.Printf("history file unavailable (%v); continuing without history", pe)
} else {
return err
}
}
Prevention
- Always point the history option at an explicit writable file path in containers/CI.
- Ensure the history file's parent directory exists before starting the REPL.
- Set HOME to a writable directory when running as a different user or in restricted environments.
- Treat history persistence as non-fatal: catch and log instead of failing the whole session.
When it happens
Trigger: Calling persist (from Repl at exit, or directly) with a history path whose parent directory does not exist, is not writable by the current user (e.g. $HOME unset or read-only, custom --history path under a protected directory), or where the path is an existing directory.
Common situations: Running in a container/CI where HOME is unset so the default history path is invalid; a read-only home directory or NFS mount; passing --history /some/dir (a directory) instead of a file path; a disk-quota or permission issue after switching users.
Understand the failure class
Background: "open() failed", "failed to open file", "cannot create file" — what a file open error means and how to fix it — this error's family across 42 libraries.
Related errors
- could not write history to %q: %v
- ErrParseMore
- unsupported query language: %q
- cannot count iterator without a valid context
- node tokens not valid
AI-assisted analysis of cayleygraph/cayley@81dcd7d73e (2026-09-06).
Data as JSON: /api/errors/858231cd19eb7f65.
Report an issue: GitHub.