gastownhall/beads · error
open log file %q: %w
Error message
open log file %q: %w
What it means
Returned by forkExecChild when the parent cannot open (create/append to) the child's log file at opts.LogFilePath with mode 0600. The child's stdout/stderr are redirected to this file, so without it the spawn cannot proceed.
Source
Thrown at internal/storage/dbproxy/proxy/endpoint.go:481
if opts.Backend == BackendExternal {
ext := opts.External
if ext.Host != "" {
args = append(args, "--external-host", ext.Host)
}
if ext.Port != 0 {
args = append(args, "--external-port", strconv.Itoa(ext.Port))
}
if ext.Socket != "" {
args = append(args, "--external-socket-path", ext.Socket)
}
if ext.KeepAlivePeriod != 0 {
args = append(args, "--external-keep-alive", ext.KeepAlivePeriod.String())
}
}
logFile, err := os.OpenFile(opts.LogFilePath, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0o600) //nolint:gosec // G304: logFilePath is caller-derived (workspace path), not user-request input
if err != nil {
return nil, fmt.Errorf("open log file %q: %w", opts.LogFilePath, err)
}
cmd := exec.Command(self, args...)
cmd.Stdin = nil
cmd.Stdout = logFile
cmd.Stderr = logFile
cmd.SysProcAttr = procAttrDetached()
birth, err := procid.Capture(os.Getpid())
if err != nil {
_ = logFile.Close()
return nil, fmt.Errorf("capture spawning process identity: %w", err)
}
marker := spawnMarker{
Schema: 1,
PID: os.Getpid(),
Birth: string(birth),
StopEpoch: stopEpoch,View on GitHub (pinned to 71377f2769)
Solutions
- Verify opts.LogFilePath's parent directory exists and is writable by the current user (mkdir -p, chown/chmod as needed).
- Correct the LogFilePath configuration to a valid writable location inside the workspace.
- Check for a read-only mount or full disk on the target path (mount, df).
- Clear any non-writable file occupying the log path and retry.
Example fix
// before: log path in a nonexistent dir
opts := OpenOpts{LogFilePath: "/nonexistent/dir/proxy.log"}
// after: ensure the directory exists and is writable
os.MkdirAll(filepath.Dir(logPath), 0o755)
opts := OpenOpts{LogFilePath: logPath} Defensive patterns
Strategy: validation
Validate before calling
if err := os.MkdirAll(filepath.Dir(opts.LogFilePath), 0o755); err != nil {
return fmt.Errorf("log dir not creatable: %w", err)
}
f, err := os.OpenFile(opts.LogFilePath, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0o600)
if err != nil { return fmt.Errorf("log path not writable: %w", err) }
f.Close() Try / catch
ep, err := GetCreateDatabaseProxyServerEndpoint(rootDir, opts)
if err != nil && strings.Contains(err.Error(), "open log file") {
return fmt.Errorf("check LogFilePath %q: directory must exist and be writable: %w", opts.LogFilePath, err)
} Prevention
- Always create the log directory before opening the proxy
- Keep LogFilePath inside the writable workspace
- Watch for read-only mounts and full disks (mount, df)
- Don't run the proxy under a UID that lacks write access to the log path
When it happens
Trigger: GetCreateDatabaseProxyServerEndpoint → spawnAndHandoff → forkExecChild when the log path's parent directory doesn't exist, the directory isn't writable, the path points to a read-only mount, or a file exists at that path without write permission.
Common situations: Workspace path on a read-only volume; misconfigured LogFilePath pointing outside the workspace; permissions changed by another tool; running under a different UID than the directory owner; disk full.
Related errors
- failed to write config.yaml: %w
- dolt path is not executable
- server: NewDoltServer: failed to determine absolute path of
- failed to create backup directory: %w
- failed to create temp file: %w
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/1d49b08f0f265376.
Report an issue: GitHub.