Skip to content

[Bug]: Daemon lock file not recovered after macOS sleep/wake kills daemon (async mode) #1041

@kmoses228

Description

@kmoses228

What broke?

The background daemon in async mode consistently gets stuck after macOS sleep/wake cycles. Every morning when I open my laptop, git-ai status fails with:

error: failed to connect to git-ai background service: daemon startup blocked: lock held at ~/.git-ai/internal/daemon/daemon.lock

The only fix is manually removing the lock file. This has happened every day for the past week, making git-ai effectively unusable without daily manual intervention.

Steps to reproduce

  1. Configure git-ai with async_mode: true (hooks-free mode)
  2. Use git-ai normally throughout the day — daemon runs fine
  3. Close laptop lid (macOS sleep) overnight
  4. Open laptop the next morning
  5. Run git-ai status
  6. Observe: daemon startup blocked: lock held at ~/.git-ai/internal/daemon/daemon.lock

Expected vs actual behavior

Expected: The stale lock auto-recovery introduced in v1.2.6 detects the dead daemon's lock and removes it, allowing a new daemon to start.

Actual: The lock file persists and blocks all git-ai operations. The previous daemon process (killed by macOS during sleep) is no longer running, but the lock is not cleaned up. Manual rm ~/.git-ai/internal/daemon/daemon.lock is required every morning.

Diagnostics (git-ai debug)

git-ai debug report

== Versions ==
Git AI version: 1.2.6
Git AI binary: ~/.git-ai/bin/git-ai
Git binary path: /opt/homebrew/bin/git
Git version: git version 2.53.0

== Platform ==
OS family: unix
OS: macos
Arch: aarch64
Kernel: Darwin 25.4.0 arm64
Shell: /bin/zsh

== Hardware ==
CPU: Apple M2 Pro
Physical cores: 10
Logical cores: 10
Memory: 16.00 GB (17179869184 bytes)

== Repository ==
In repository: true
(private repo, redacted)

== Git AI Config ==
  runtime_config:
    {
      "git_path": "/opt/homebrew/bin/git",
      "exclude_prompts_in_repositories": [],
      "include_prompts_in_repositories": [],
      "allow_repositories": [],
      "exclude_repositories": [],
      "telemetry_oss_disabled": false,
      "telemetry_enterprise_dsn": null,
      "disable_version_checks": false,
      "disable_auto_updates": false,
      "update_channel": "latest",
      "feature_flags": {
        "rewrite_stash": false,
        "inter_commit_move": false,
        "auth_keyring": false,
        "async_mode": true,
        "git_hooks_enabled": false,
        "git_hooks_externally_managed": false
      },
      "api_base_url": "https://usegitai.com",
      "prompt_storage": "default",
      "default_prompt_storage": null,
      "api_key": null,
      "quiet": false,
      "custom_attributes": {},
      "git_ai_hooks": {}
    }

== Git AI Login ==
Credential backend: file
Status: logged in

== Git AI Environment ==
No GIT_AI_* environment variables are set.

Extra context (optional)

Daemon log files — all 0 bytes (no panics/crashes logged), but a new daemon log is created each day, confirming the daemon dies and restarts repeatedly:

$ ls -la ~/.git-ai/internal/daemon/logs/
-rw-r--r--  0 Apr  2 16:25 38301.log
-rw-r--r--  0 Apr  3 17:39 27141.log
-rw-r--r--  0 Apr  5 10:30 76398.log
-rw-r--r--  0 Apr  6 11:08 54658.log
-rw-r--r--  0 Apr  6 11:11 57491.log
-rw-r--r--  0 Apr  6 13:46 12289.log
-rw-r--r--  0 Apr  6 14:06 22878.log
-rw-r--r--  0 Apr  7 15:07 74718.log
-rw-r--r--  0 Apr  8 09:21 3679.log
-rw-r--r--  0 Apr  8 17:24 67451.log
-rw-r--r--  0 Apr  9 10:02 17560.log

Note: there is one log file (62356.log from April 2, pre-upgrade) with an old UTF-8 panic in rebase_authorship.rs — this is NOT the current issue. No panics since upgrading to v1.2.6.

macOS sleep/wake frequency — the laptop cycles through sleep/wake very frequently (124 cycles in ~2 days), which likely increases the chance of hitting the stale-lock edge case:

$ pmset -g log | grep "Total Sleep/Wakes"
Total Sleep/Wakes since boot at 2026-04-07 21:14:41 :124

When the daemon is running, bg status reports healthy:

{
  "ok": true,
  "data": {
    "family_key": "<redacted>/.git",
    "last_error": null,
    "latest_seq": 13
  }
}

Hypothesis: The daemon is getting killed by macOS during sleep (SIGKILL, App Nap, or memory pressure) without a chance to clean up the lock file. The v1.2.6 auto-recovery detects some stale locks but doesn't handle this specific macOS sleep-death scenario. Since the daemon writes nothing to its log file before dying (0-byte logs), it's likely an external kill rather than an internal error.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions