{"record":{"id":"858231cd19eb7f65","repo":"cayleygraph/cayley","slug":"could-not-open-q-to-append-history-v","errorCode":null,"errorMessage":"could not open %q to append history: %v","messagePattern":"could not open %q to append history: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"internal/repl/repl.go","lineNumber":275,"sourceCode":"\t\t\tos.Exit(1)\n\t\t}\n\n\t\tos.Exit(0)\n\t}()\n\n\tf, err := os.Open(path)\n\tif err != nil {\n\t\treturn term, err\n\t}\n\tdefer f.Close()\n\t_, err = term.ReadHistory(f)\n\treturn term, err\n}\n\nfunc persist(term *liner.State, path string) error {\n\tf, err := os.OpenFile(path, os.O_RDWR|os.O_APPEND|os.O_CREATE, 0666)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"could not open %q to append history: %v\", path, err)\n\t}\n\tdefer f.Close()\n\t_, err = term.WriteHistory(f)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"could not write history to %q: %v\", path, err)\n\t}\n\treturn term.Close()\n}\n","sourceCodeStart":257,"sourceCodeEnd":284,"githubUrl":"https://github.com/cayleygraph/cayley/blob/81dcd7d73e45136bc0d01802a8ba4685d8a533eb/internal/repl/repl.go#L257-L284","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\ncayley repl --history ~/nonexistent-dir/history\n// after\nmkdir -p ~/cayley && cayley repl --history ~/cayley/history","handlingStrategy":"try-catch","validationCode":"dir := filepath.Dir(historyPath)\nif _, err := os.Stat(dir); os.IsNotExist(err) {\n\tos.MkdirAll(dir, 0o755)\n}\nif f, err := os.OpenFile(historyPath, os.O_RDWR|os.O_APPEND|os.O_CREATE, 0o666); err != nil {\n\treturn err\n} else {\n\tf.Close()\n}\n","typeGuard":null,"tryCatchPattern":"if err := repl.Repl(ctx, h, lang, timeout); err != nil {\n\tvar pe *fs.PathError\n\tif errors.As(err, &pe) {\n\t\tlog.Printf(\"history file unavailable (%v); continuing without history\", pe)\n\t} else {\n\t\treturn err\n\t}\n}\n","preventionTips":["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."],"tags":["go","repl","filesystem","history"],"backgroundTag":"file-open-failed","analyzedSha":"81dcd7d73e45136bc0d01802a8ba4685d8a533eb","analyzedAt":"2026-09-06T06:14:12.358Z","contentChangedAt":"2026-09-06T06:14:12.358Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}