gastownhall/beads · error
failed to write interactions log entry: %w
Error message
failed to write interactions log entry: %w
What it means
Append writes the fully encoded JSON line in a single f.Write call (deliberately avoiding bufio to keep O_APPEND writes atomic), and wraps any write failure as "failed to write interactions log entry". This indicates the file was opened successfully but the data could not be written — typically disk full, I/O errors, or the file descriptor going bad. A partial write here can corrupt a JSONL line, so the error is not recoverable within the same call.
Source
Thrown at internal/audit/audit.go:151
}
f, err := os.OpenFile(p, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0644) // nolint:gosec // intended permissions
if err != nil {
return "", fmt.Errorf("failed to open interactions log: %w", err)
}
defer func() { _ = f.Close() }() // Best effort: file close in defer after flush
// Marshal to a single byte slice and write atomically.
// Using bufio.NewWriter could split into multiple write() syscalls,
// which interleave under concurrent O_APPEND and corrupt lines.
var buf bytes.Buffer
enc := json.NewEncoder(&buf)
enc.SetEscapeHTML(false)
if err := enc.Encode(e); err != nil {
return "", fmt.Errorf("failed to marshal interactions log entry: %w", err)
}
if _, err := f.Write(buf.Bytes()); err != nil {
return "", fmt.Errorf("failed to write interactions log entry: %w", err)
}
return e.ID, nil
}
// AppendIfEnabled appends only when the optional JSONL sidecar is enabled.
func AppendIfEnabled(e *Entry) (string, error) {
if !Enabled() {
return "", fmt.Errorf("audit JSONL sidecar is disabled; set audit.enabled=true or BD_AUDIT_ENABLED=1 to write %s", FileName)
}
return Append(e)
}
// LogFieldChange logs a field change (status, assignee, priority, etc.) to the
// optional JSONL sidecar when it is enabled. First-class issue history is
// recorded separately in the database events tables. Best-effort: errors are
// silently ignored so sidecar logging never blocks operations.
// Optional reason is included when non-empty (e.g., close reason, cleanup rule).View on GitHub (pinned to 71377f2769)
Solutions
- Free disk space or increase the quota on the volume holding .beads/.
- Check the filesystem for errors (dmesg / SMART) if EIO is reported.
- Rotate or truncate an oversized interactions.jsonl.
- Retry the append once — transient NFS hiccups may clear.
- Verify RLIMIT_FSIZE is not limiting the process (ulimit -f).
Example fix
// before
if _, err := audit.AppendIfEnabled(e); err != nil {
log.Fatal(err) // "failed to write interactions log entry: no space left on device"
}
// after
if _, err := audit.AppendIfEnabled(e); err != nil {
if strings.Contains(err.Error(), "no space left") {
pruneAuditLog(".beads/interactions.jsonl") // rotate/truncate
}
return err
} Defensive patterns
Strategy: retry
Validate before calling
var st syscall.Statfs_t
if err := syscall.Statfs(".beads", &st); err == nil && st.Bavail*uint64(st.Bsize) < 1<<20 {
return fmt.Errorf("low disk space for audit log")
} Try / catch
if _, err := audit.AppendIfEnabled(e); err != nil {
if strings.Contains(err.Error(), "failed to write interactions log entry") {
log.Printf("audit write failed (disk full?): %v", err)
}
return err
} Prevention
- Monitor free space on the volume holding .beads/.
- Rotate/truncate interactions.jsonl before it grows unbounded.
- Avoid audit logging to network filesystems prone to EIO.
- Set disk-space alerts in CI runners.
When it happens
Trigger: Disk quota or filesystem full when appending; EIO from failing hardware or network filesystems (NFS); file removed/unlinked while open in exotic setups; RLIMIT_FSIZE reached.
Common situations: CI runners with small ephemeral disks accumulating large audit logs; home directories on full NFS mounts; containers hitting their writable-layer size limit.
Related errors
- failed to write temp file: %w
- truncating lock file: %w
- failed to read backup state: %w
- failed to sync temp file: %w
- failed to write issue %s: %w
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/e85e4571ea9fb1b2.
Report an issue: GitHub.