Skip to content

Periodic snapshot-maintenance git gc fails 100% from first tick in some sessions, while event-driven git spawns in the same session succeed #43877

Closed as not planned

Description

@denisagniel

Summary

A session's periodic snapshot-maintenance call (git gc --prune=7.days, fired
roughly hourly) can fail 100% of the time, from the very first scheduled tick, for
the entire lifetime of that session
— while, in the exact same session, the
event-driven snapshot spawns (diff-files/ls-files, fired on nearly every tool
call/file touch) and the interactive Bash tool succeed continuously and repeatedly.

This is a different, much lower-severity failure mode than the one described in
#43876 — that one is a mid-session, cross-process, all-spawns wedge; this one is
narrow (only the periodic maintenance call), permanent-from-tick-1 rather than
triggered mid-session, and doesn't appear to affect anything user-facing.

Evidence

Session run=d4c57129 (created 2026-08-20, still active), 13 hourly maintenance
attempts logged, 13 failures, 0 successes:

timestamp=2026-08-21T11:13:19.937Z level=WARN run=d4c57129 message="cleanup failed" exitCode=1 stderr="Command failed: git --git-dir /Users/.../opencode/snapshot/<hash>/<hash> --work-tree /Users/.../<project> gc --prune=7.days: Unknown: ChildProcess.spawn (git --git-dir /Users/.../opencode/snapshot/<hash>/<hash> --work-tree /Users/.../<project> gc --prune=7.days)"

Same pattern repeats hourly (drifting by seconds each hour) since session creation,
with zero successful cleanup events ever logged for this session id.

In the same session, dozens of tracking hash=<real-hash> cwd=... git=... lines
show the event-driven snapshot tracker succeeding repeatedly, and the interactive
Bash tool (git status, git log, git diff, etc., evaluated+allowed) works
throughout. Manually re-running the exact failing gc command, with the identical
--git-dir/--work-tree pair, from an interactive shell succeeds instantly
(exit 0).

Why this looks like a captured-context bug specific to the maintenance timer

  • The command, args, and target paths are all fine (proven by the manual
    reproduction).
  • The session's general spawn capability is fine (proven by the successful
    event-driven git calls and Bash tool calls in the same session).
  • Only the periodically-scheduled maintenance call is affected, and it's affected
    100% of the time starting from its very first invocation.

This is consistent with the periodic-maintenance timer's closure capturing a
cwd/env/PATH value once, at session- or snapshot-creation time, that differs
from whatever the event-driven code path builds fresh on each call — rather than
any resource, path-validity, or concurrency issue (no other session was ever found
running a gc against the same snapshot dir at an overlapping time, so lock
contention was also ruled out).

Consequence

Low severity: affected sessions' snapshot git-dirs never get pruned by the periodic
gc, which is a slow disk-bloat issue for ~/.local/share/opencode/snapshot/
(measured 28MB total across all sessions on this machine at time of investigation —
not currently a practical problem, but presumably compounds over time on a machine
that's rarely fully restarted).

Ask

If the periodic maintenance scheduler builds its child_process.spawn options
differently from the event-driven git-tracking code path (e.g. captured once in a
setInterval/timer closure vs. built fresh per call), that's the first place I'd
look — specifically whether cwd or env differs between the two call sites.

Environment

  • OpenCode version: 1.18.15
  • Platform: macOS Sonoma 23.6.0, aarch64

Activity

  1. arthurjd commented on Aug 29, 2026

    @arthurjd

    Related context from the missing-objects failure mode: PR #46037 adds cleanup that prunes stale tmp_pack_* files after every snapshot gc run (success or failure) and rebuilds the snapshot store when gc fails on missing objects. It doesn't target the spawn failure described here, but the tmp_pack pruning covers the disk-bloat consequence for any cleanup failure mode. For the captured-context hypothesis: on current dev the periodic loop and the event-driven path use the same git helper, building spawn options fresh on every call — so if that was the cause in 1.18.15, it may already be addressed upstream.

  2. thdxr commented on Oct 11, 2026

    @thdxr
    Member

    Thanks for the report! OpenCode 2.0 is now out and development is focused on V2, so we're closing issues filed against OpenCode 1. Please upgrade (opencode upgrade --major, details: https://anoma.ly/notes/opencode-2-0), and if this is still relevant on 2.0, reopen this issue or open a new one with your 2.0 version.

    — from 𝕺𝖕𝖊𝖓𝕮𝖔𝖉𝖊

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions