Skip to content

Guard against PM2 socket paths over the macOS 104-char limit#34

Merged
fredrivett merged 2 commits into
mainfrom
fredrivett/socket-path-length-guard
Jul 2, 2026
Merged

Guard against PM2 socket paths over the macOS 104-char limit#34
fredrivett merged 2 commits into
mainfrom
fredrivett/socket-path-length-guard

Conversation

@fredrivett

@fredrivett fredrivett commented Jul 1, 2026

Copy link
Copy Markdown
Owner

What

Guards against PM2 workspaces whose socket path exceeds macOS's 104-character sun_path limit.

Background

A workspace whose PM2_HOME is long enough that PM2_HOME + /interactor.sock exceeds 104 chars can never bind its daemon socket — the daemon fails with EINVAL. Worse, because PM2 auto-spawns a daemon on any command when it can't reach one, every pm2 jlist/pm2 kill against such a home spawns a fresh broken daemon that immediately dies and orphans, piling up zombie God Daemons. reeve's own polling was one of the things feeding that cascade (it runs jlist whenever a live pid file is present).

Seen in the wild with a long Conductor branch name:

/Users/…/.pm2-fredrivett-eng-4058-fix-re-scanning-to-be-page-by-page-and-show-scan-button-in/interactor.sock  = 111 chars

Change

  • PM2Environment.socketPathTooLong — pure length check (PM2_HOME + /interactor.sock > 104).
  • fetchProcessesSync returns early for such workspaces without running any pm2 command, so reeve never auto-spawns a broken daemon into them.
  • The workspace shows a tailored "Workspace path too long" banner explaining the real cause and fix (recreate with a shorter name), instead of the generic "socket broken or stale."

This is defense-in-depth: it stops reeve from making the situation worse and labels it accurately. The root-cause prevention (shorter PM2_HOME names) lives in the workspace launcher that sets PM2_HOME, which is being addressed separately.

Budget

$HOME/ (19) + .pm2-<name> + /interactor.sock (16) ≤ 104 → workspace-name portion max ≈ 64 chars.

Tests

5 new tests covering the boundary (88-char home == 104-char path is fine, 89 is too long), the real over-long path, and the instance property. Full suite green (138). swiftlint --strict clean.

🤖 Generated with Claude Code


Summary by cubic

Prevents broken PM2 daemons by detecting when the PM2 socket path exceeds macOS’s 104‑byte limit and skipping any pm2 commands; the UI now shows a clear “Workspace path too long” message with the fix.

  • Bug Fixes
    • Added PM2Environment.socketPathTooLong (UTF‑8 byte-length check for PM2_HOME + "/interactor.sock").
    • fetchProcessesSync returns early with a sentinel error and never spawns a daemon for these workspaces.
    • UI shows a tailored “Workspace path too long” banner with guidance to recreate the workspace with a shorter name; “Kill daemon” remains available and sends SIGKILL directly (no pm2).
    • Added tests for boundary conditions, instance property, and byte-count vs grapheme cases.

Written for commit 7f1a180. Summary will update on new commits.

Review in cubic

A workspace whose PM2_HOME makes the socket path (PM2_HOME +
/interactor.sock) exceed macOS's 104-char sun_path limit can never bind
its daemon socket — every pm2 command auto-spawns a fresh daemon that
instantly breaks with EINVAL, piling up zombies.

reeve now detects this in fetchProcessesSync and returns early without
running any pm2 command, so it stops contributing to the spawn cascade.
The workspace shows a tailored "Workspace path too long" banner pointing
at the real fix (shorter name) instead of the generic socket error.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

2 issues found across 4 files

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment thread Sources/Reeve/Views/EnvironmentSectionView.swift
Comment thread Sources/Reeve/Models/PM2Environment.swift Outdated
- Measure the socket path in UTF-8 bytes, not grapheme clusters:
  sun_path is a fixed 104-byte C buffer, so a multi-byte character in
  the path would otherwise under-report and slip past the check.
- Fix the misleading comment on the path-too-long banner: reeve avoids
  polling with pm2 (which auto-spawns), but "Kill daemon" is still
  offered and is safe — it SIGKILLs any zombie directly, no pm2 command.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@fredrivett fredrivett merged commit 04b578a into main Jul 2, 2026
2 checks passed
@fredrivett fredrivett deleted the fredrivett/socket-path-length-guard branch July 2, 2026 12:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant