DeepSeek Harness macOS Dock duplicates: 939 session.lock
On seeing "939 session.lock files that are never reclaimed", almost every instinct points at "lock leak" and reaches for a cleanup script — which is exactly the step that turns cleanup into a concurrency bug. The same report also contains the other half: Dock icons piling up, and that one is the real defect (#10757). Read the two sentences separately and the conclusions are completely different.
DeepSeek Harness: What "939 lock files" actually means
It only says 939 sessions have existed in this workspace; it does not say 939 processes are alive, nor that 939 locks are held.
- Count them:
find ~/.dsh/sessions -name "session.lock" | wc -l, which the community found to be 939. - Look at the time distribution: the oldest is from a month earlier, and 09-26 through 09-28 alone contributed 89, 115, and 146. That staircase looks more like a launch loop than natural session growth.
- Look at one file: zero bytes, identical to a live session's lock — and that is exactly why it "looks like a leak".
- Look at real activity: only 3 workspace directories were touched that day, and only one session in them was active.
- So the count has nothing to do with live processes, only with historical session count.
DSH plugin: What lock files really mean: the file stays, the lock may not
POSIX lock files are never deleted by design: the leftover file keeps a stable inode so later lockers can verify it is the same object; the kernel arbitrates ownership, not the file itself.
- When the holder exits the kernel releases the lock but the file remains — that is "released", not "leaked".
- Deleting the file changes the inode, so later lockers no longer see the same object.
- Deleting a session lock that is in use abandons the whole point of its existence: mutual exclusion.
- The community was blunt: such a "cleanup plugin" looks like housekeeping but behaves like a mutex bug.
- If the file count is genuinely a problem, the right move is core providing a bounded directory or an explicit retention rule, not deleting at the point of use.
DeepSeek Harness: What "a row of Dock icons" means
It means every launch produced a new process and the system treats them as separate instances; what is missing is single-instance protection in the main process.
- Rule out the install state first:
ls -d /Applications/*Harness*.app | wc -lreturns 1, a single app. - Then rule out extra pins:
defaults read com.apple.dock persistent-apps | grep -c "com.deepseek.dsh"returns 1. ~/Applications,/Users/Shared, and the desktop have no second copy, and there is no launcher on the desktop.- Check Info.plist:
LSMultipleInstancesProhibitedappears 0 times, andLSUIElementis absent too. - So LaunchServices starts a new process on every double-click, and each process takes a Dock icon.
- The same root cause explains another old symptom: after quitting, you have to click the icon twice to reopen it.
DSH Plugin: Why both appear in one report
They share the trigger "repeated launch", but one is a runtime symptom and the other a filesystem leftover, and the handling is opposite.
| Dimension | Duplicate Dock icons | session.lock accumulation |
|---|---|---|
| Is it a defect? | Yes | No, by design |
| Direct evidence | one app, one pin, missing single-instance key | 0-byte files, holders gone |
| Can it be cleaned? | Returns after a restart | Should not be cleaned |
| Fix owner | core main process | core (retention policy) or leave it |
That is also why the community reply only addresses the second half: mixing the two produces the false causal claim that deleting locks reduces Dock icons.
DeepSeek Harness: Thirty-second check: look at the two numbers separately
Two commands are enough: one counts the install state, one counts the runtime state; the install state is always 1, the runtime state changes, and neither is evidence of a lock leak.
# 1. install state: should be exactly 1
ls -d /Applications/*Harness*.app | wc -l
defaults read com.apple.dock persistent-apps | grep -c "com.deepseek.dsh"
# 2. runtime state: grows with the number of launches
find ~/.dsh/sessions -name "session.lock" | wc -l
# 3. single-instance declaration: without it, every launch is a new process
/usr/libexec/PlistBuddy -c "Print :LSMultipleInstancesProhibited" \
"/Applications/DeepSeek Harness.app/Contents/Info.plist"
If the third reports Does Not Exist, it matches the community observation: no single-instance protection is declared, so repeated launches directly spawn new processes.
DSH plugin: What you can and cannot do
What you can do: reduce repeated launches and tidy desktop shortcuts. What you cannot do: delete locks or expect a plugin to fix single-instance behavior.
- During observation, confirm the symptom first: double-click from the Dock over several days and record the icon count alongside
find ... session.lock | wc -l. - Do not write a script to bulk-delete
session.lock, especially not while the app is running. - To relieve icon pileup temporarily, quit all instances and reopen once; the Dock returns to a single icon.
- Keep only one launch entry on the desktop and in the Dock so you do not double-click by accident.
- The real fix requires the main process to call
app.requestSingleInstanceLock()and exit when it fails, or tofocus()the existing window in thesecond-instanceevent. - Alternatively declare
LSMultipleInstancesProhibitedin Info.plist so LaunchServices enforces it. - If the lock half is to improve, core should sweep locks whose holder PID is dead and which have no active writer at startup, rather than asking users to delete by hand.
Cautions
Do not clean a lock file to fix a Dock icon.
- Do not read "0 bytes" as "empty file, safe to delete". Live and abandoned locks are indistinguishable at the file level, which is exactly why they cannot be cleaned casually.
- Do not infer process count from icon count. Dock icons accumulate from launch history.
- Do not expect a plugin to fix the Dock. The second launch happens before any plugin loads.
- Record the version and OS. The community report is based on 0.2.0-rc.2, and behavior may change across versions.
- Separate "many lock files" from "lock wait timeout". The latter is a different problem; its error only gives a path and should not be fixed by deleting files either.
If your Dock duplicates appear only when multiple app copies are installed, that is an install-state problem — remove the extra copies.See DeepSeek Harness desktop: no window, crash, EMFILE, 80s for the related case.
FAQ
No, it is not a lock leak: DeepSeek Harness never deletes lock files by design, because they keep the same inode so later lockers can verify the same object, and the kernel arbitrates ownership rather than the file's existence. Zero bytes with the holder gone means the lock is released, not leaked.
Not advisable: deleting those lock files in DeepSeek Harness gives up the mutual exclusion a session lock is supposed to provide, turning cleanup into a concurrency bug. If the count is the problem, core should offer a bounded directory or retention policy, not deletion at the point of use.
The Dock shows repeated icons because the DeepSeek Harness desktop app has no single-instance protection. Info.plist does not declare LSMultipleInstancesProhibited, so LaunchServices starts a new process on every open or double-click, and each process occupies its own Dock icon.
Neither is true for DeepSeek Harness: the community checked and found /Applications has one app, and Dock's persistent-apps has one com.deepseek.dsh pin. The duplication comes from runtime state, not the installation.
No, a plugin cannot fix the DeepSeek Harness Dock duplication, because the second launch happens before any plugin loads, so single-instance protection must be done by the main process early in startup; it is a core decision.
Related Terms
- session.lock
- Every DeepSeek Harness session directory is guarded by `session.lock`, a POSIX lock file that ensures a single writer per session. The file is never deleted by design, and the holder exiting counts as the lock being released.— https://github.com/deepseek-ai/deepseek-harness/discussions/10757
- LSMultipleInstancesProhibited
- LSMultipleInstancesProhibited is a macOS Info.plist boolean that prevents launching multiple instances of one app. Without it, LaunchServices starts a new process for each open action instead of activating the existing window.— https://github.com/deepseek-ai/deepseek-harness/discussions/10757
- LaunchServices
- LaunchServices is the macOS system service that registers and launches apps. It decides between reusing an existing instance and starting a new process based on Info.plist declarations, which is where single-instance behavior must be declared.— https://github.com/deepseek-ai/deepseek-harness/discussions/10757
- inode
- An inode is the filesystem number identifying one file entity. A lock file must keep the same inode so later lockers can confirm they are locking the same object, which is why the file cannot be deleted casually.— https://github.com/deepseek-ai/deepseek-harness/discussions/10757
Sources
- #10757 — macOS: Dock accumulates duplicate icons — no single-instance lock, 939 stale session.lock· deepseek-ai (GitHub Discussions)
- deepseek-ai/deepseek-harness (source repository)· GitHub