Skip to content

Local MCP servers fail with 'spawn ENOENT' after version update — PATH not inherited on macOS #26356

Closed

Description

@leoncheng57

Bug description

After updating OpenCode (Desktop app on macOS), all local MCP servers fail to start. The spawned processes get a minimal system PATH (/usr/bin:/bin:/usr/sbin:/sbin) that excludes Homebrew, nvm, and other user-installed toolchains.

This manifests as two distinct failures:

  1. spawn <command> ENOENT — bare command names like npx, node, python3 can't be resolved
  2. MCP error -32000: Connection closed — even with absolute paths in command, child processes (e.g., npx spawning node) fail because they inherit the stripped PATH

This is a regression — the same config worked on the previous version. The MCP server config has not changed (verified via backup files).

Steps to reproduce

  1. Install OpenCode Desktop on macOS (Apple Silicon)
  2. Have Node.js/npx installed via Homebrew at /opt/homebrew/bin/
  3. Configure a local MCP server using a bare command name:
    {
      "mcp": {
        "my-server": {
          "type": "local",
          "command": ["npx", "-y", "@notionhq/notion-mcp-server"],
          "enabled": true
        }
      }
    }
  4. Launch OpenCode — the MCP server fails to start

Expected behavior

OpenCode should inherit the user's shell PATH (or at least /opt/homebrew/bin) when spawning local MCP server processes, so that commands like npx, node, etc. resolve correctly — as they did in the previous version.

Actual behavior

Phase 1 — with bare command names:

ERROR service=mcp key=notion-work command=["npx","-y","@notionhq/notion-mcp-server"]
  error=spawn npx ENOENT local mcp startup failed

Phase 2 — after adding absolute paths to command, child processes still fail:

ERROR service=mcp key=notion-work command=["/opt/homebrew/bin/npx","-y","@notionhq/notion-mcp-server"]
  error=MCP error -32000: Connection closed local mcp startup failed

The underlying cause of phase 2 is npx spawning node which isn't on the inherited PATH:

env: node: No such file or directory

This affects all executables not on the minimal system PATH:

  • npx → ENOENT
  • node → ENOENT (both directly and as a child of npx)
  • python3 (Homebrew) → ENOENT
  • uvx → ENOENT
  • Custom CLIs like deepctl → ENOENT

Workaround

Both absolute paths in command and an explicit PATH in environment are required:

"notion-work": {
  "type": "local",
  "command": ["/opt/homebrew/bin/npx", "-y", "@notionhq/notion-mcp-server"],
  "environment": {
    "PATH": "/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin",
    "NOTION_TOKEN": "..."
  },
  "enabled": true
}

Using absolute paths in command alone is not sufficient — the child processes still inherit the stripped PATH and fail.

Environment

  • OS: macOS (Apple Silicon)
  • OpenCode: Desktop app (latest as of 2026-05-08)
  • Node: Installed via Homebrew at /opt/homebrew/bin/
  • Shell: zsh

Logs

From ~/.local/share/opencode/log/:

# Phase 1: bare commands
ERROR 2026-05-08T14:40:05 service=mcp key=notion-work command=["npx","-y","@notionhq/notion-mcp-server"] error=spawn npx ENOENT local mcp startup failed
ERROR 2026-05-08T14:40:05 service=mcp key=excalidraw command=["node","..."] error=spawn node ENOENT local mcp startup failed

# Phase 2: absolute paths but no PATH env
ERROR 2026-05-08T14:56:40 service=mcp key=notion-work command=["/opt/homebrew/bin/npx","-y","@notionhq/notion-mcp-server"] error=MCP error -32000: Connection closed local mcp startup failed

The same config worked correctly on 2026-05-05 (desktop logs show successful MCP connections with only the expected -32601: Method not found for prompts).

Additional context

This likely affects all macOS users who install tools via Homebrew or nvm, since the Desktop app spawns child processes with a stripped-down PATH that excludes /opt/homebrew/bin, ~/.nvm/versions/node/*/bin, ~/.local/bin, etc.

Activity

  1. github-actions commented on May 8, 2026

    @github-actions
    Contributor

    This issue might be a duplicate of existing issues. Please check:

    If your issue is the same, please add a "+1" or relevant details to those threads instead.

  2. leoncheng57 commented on May 8, 2026

    @leoncheng57
    Author

    Update: absolute paths alone are insufficient

    Using absolute paths for the command (e.g., /opt/homebrew/bin/npx) fixes the initial spawn ENOENT, but the spawned process inherits the stripped PATH. So npx finds itself but then fails when it tries to spawn node as a child:

    env: node: No such file or directory
    

    This causes MCP error -32000: Connection closed for all npx-based servers.

    Full workaround requires both:

    1. Absolute path in command
    2. Explicit PATH in environment:
    "notion-work": {
      "type": "local",
      "command": ["/opt/homebrew/bin/npx", "-y", "@notionhq/notion-mcp-server"],
      "environment": {
        "PATH": "/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin",
        "NOTION_TOKEN": "..."
      },
      "enabled": true
    }

    This is a significant UX regression — previously neither was needed.

  3. leoncheng57 commented on May 11, 2026

    @leoncheng57
    Author

    Possibly related: opencode mcp auth <name> fails with opaque "JSON Parse error" when mcp-auth.json is corrupted

    Hitting this on v1.14.41 (macOS). Different code path from the spawn-ENOENT issue above, but filing here since it's the active MCP-pain thread — happy to split into its own issue if preferred.

    Symptom

    $ opencode mcp auth gitlab-mcp
    ┌  MCP OAuth Authentication
    Error: Unexpected error, check log file at /Users/me/.local/share/opencode/log/2026-05-11T160949.log for more details
    
    JSON Parse error: Unable to parse JSON string
    

    The log file contains only the standard config-loading lines and stops before any actionable error — nothing identifies the offending file.

    Root cause
    ~/.local/share/opencode/mcp-auth.json was corrupted with a stray extra } at EOF:

    ...
      }
    }
    }   ← extra
    

    JSON.parse rejects this with Extra data (the underlying message that gets swallowed into the generic "Unable to parse JSON string"). Fix was to strip the trailing brace and re-serialize — opencode mcp auth then works.

    Two suggestions

    1. Surface the file path in the error. Wrapping the JSON.parse on the auth store with a try/catch that re-throws with the path would have made this a 10-second fix instead of a log-dive. Something like:

      Failed to parse /Users/me/.local/share/opencode/mcp-auth.json: Extra data at position 7110
      
    2. Write mcp-auth.json atomically. A trailing extra } strongly suggests a non-atomic write (write-in-place with a previous longer payload not fully overwritten, or an interrupted write merging with stale tail). Standard tmp-file + rename(2) pattern would prevent this entire failure mode.

    Let me know if you'd like a separate issue for this — the symptom (opencode mcp auth rather than runtime MCP spawning) is genuinely distinct from the original report, even though both live in the MCP subsystem.

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