# Common Issues When Using different-ai/openwork and How to Fix Them

> Troubleshoot common issues with different-ai/openwork including lock contention UI glitches stuck loaders and monorepo dependency mismatches Learn how to fix these problems for a smoother development experience

- Repository: [Different AI/openwork](https://github.com/different-ai/openwork)
- Tags: how-to-guide
- Published: 2026-08-04

---

**The most common problems with OpenWork involve development profile lock contention on Windows, UI glitches in the in-app browser, stuck loading indicators, and monorepo dependency mismatches across its Electron-MCP-Den architecture.**

OpenWork is a **local-first, cloud-ready desktop app** that unifies AI agents, skills, and MCPs behind a single control surface. Its three-layer architecture—**Electron desktop runtime**, **remote MCP service**, and **cloud-hosted Den console**—creates multiple failure points where platform-specific behaviors and configuration drift cause friction. Understanding how these layers interact, and where the open-source codebase handles state and events, is essential for troubleshooting effectively.

## Development Profile Locking and Port Contention

The most frequently reported startup failure occurs when `pnpm dev` or `pnpm dev:worktree` aborts with a profile lock error or CDP port conflict. OpenWork uses **profile-based isolation** via the `OPENWORK_DEV_PROFILE` environment variable to separate credentials, ports, and runtime state between development contexts.

### Root Cause: Stale Lock Files

Each profile creates a lock file to prevent multiple Electron instances from sharing state. When a process crashes or exits uncleanly, the lock persists and blocks subsequent launches. The lock location defaults to `~/.openwork/dev-profile-lock` unless overridden.

### Solution: Force a Fresh Profile

```bash

# Remove stale lock and start with isolated profile

rm -rf ~/.openwork/dev-profile-lock
OPENWORK_DEV_PROFILE=my-feature \
OPENWORK_ELECTRON_USE_MOCK_KEYCHAIN=1 \
pnpm dev

```

The `OPENWORK_DEV_PROFILE=my-feature` parameter forces allocation of a new CDP port and lock file. Setting `OPENWORK_ELECTRON_USE_MOCK_KEYCHAIN=1` prevents macOS keychain authorization dialogs from blocking startup—particularly useful in CI or headless environments.

## Platform-Specific Runtime Issues

Windows and macOS exhibit distinct failure modes due to how Electron handles STDIO, sandboxing, and native system integrations.

### Windows: Dev Server Blocking and Task Abortion

Issue #3457 documents `npm run dev` blocking the agent process on Windows, causing tasks to abort when the terminal remains in the foreground. This stems from Windows command-line buffering interfering with Electron's STDIO pipe handling.

**Workaround**: Launch through a detached console or force new process group:

```bash

# Force new console window on Windows

cmd /c start pnpm dev

# Or use cross-env to isolate environment

npx cross-env OPENWORK_DEV_PROFILE=win-dev pnpm dev

```

Adding `--max-old-space-size=4096` to Node flags also prevents long GC pauses that compound the blocking behavior.

### In-App Browser: Right-Click and Passkey Hangs

Issue #3459 reports non-functional right-click menus and multi-minute passkey prompt hangs in the embedded Chromium browser. The root cause lies in `contextIsolation` settings and missing `contextmenu` event registration in the renderer preload.

**Fix in preload script** ([`apps/desktop/src/electron/preload.ts`](https://github.com/different-ai/openwork/blob/main/apps/desktop/src/electron/preload.ts)):

```typescript
const { contextBridge, ipcRenderer } = require('electron');

// Expose safe API to renderer
contextBridge.exposeInMainWorld('openwork', {
  showContextMenu: (x: number, y: number) => 
    ipcRenderer.send('show-context-menu', { x, y })
});

```

**Fix in renderer** ([`apps/desktop/src/renderer/browser.ts`](https://github.com/different-ai/openwork/blob/main/apps/desktop/src/renderer/browser.ts)):

```typescript
window.addEventListener('contextmenu', (e) => {
  e.preventDefault();
  // Forward to main process for native menu
  window.openwork.showContextMenu(e.clientX, e.clientY);
});

```

For passkey hangs, ensure `navigator.credentials` polyfills are loaded before WebAuthn requests, or disable passkey auto-prompt via `OPENWORK_SKIP_PASSKEY=1`.

### Stuck Session Loading Indicator

Issue #3462 describes the loading spinner persisting after task completion. The bug resides in [`apps/desktop/src/renderer/loading.tsx`](https://github.com/different-ai/openwork/blob/main/apps/desktop/src/renderer/loading.tsx) where the `runTask` promise lacks guaranteed cleanup.

**Correct pattern**:

```typescript
// loading.tsx
async function runTask(task: () => Promise<void>): Promise<void> {
  setLoading(true);
  try {
    await task();
  } catch (err) {
    setError(err);
    throw err;
  } finally {
    setLoading(false); // Guaranteed execution
  }
}

```

The `finally` block ensures `setLoading(false)` runs regardless of success or failure, eliminating the stuck spinner state.

## MCP and Remote Service Connectivity

OpenWork's **Model-Control-Plane** exposes `search_capabilities` and `execute_capability` tools via `https://api.openworklabs.com/mcp/agent`. Failures here typically manifest as "MCP tool not found" or timeout errors in Claude Code, Codex, or Cursor integrations.

### Common Causes

- **Stale API key** in dev profile credentials
- **CORS rejection** from custom Den deployments
- **Version mismatch** between local client and remote MCP schema

### Debugging Steps

```bash

# Verify MCP endpoint health

curl -H "Authorization: Bearer $OPENWORK_API_KEY" \
  https://api.openworklabs.com/mcp/agent/health

# Test capability search locally

npx openwork-cli mcp search --query "file-ops"

```

The CLI source in [`packages/mcp/src/index.ts`](https://github.com/different-ai/openwork/blob/main/packages/mcp/src/index.ts) implements the client-side protocol; check `MCPClient.searchCapabilities()` and `executeCapability()` method signatures when building custom integrations.

## Dependency and Build Tool Conflicts

OpenWork uses **pnpm workspaces** with **Turborepo** for build orchestration. Dependency bumps—especially in `postcss`, `vite`, or `turbo`—frequently break builds when lock files desynchronize across packages.

### Symptoms

- `Module not found` errors after pulling main
- `turbo` cache corruption causing stale builds
- Type conflicts between workspace package versions

### Resolution Workflow

```bash

# From repository root

rm -rf node_modules **/node_modules pnpm-lock.yaml
pnpm install          # Regenerate unified lock

pnpm run build        # Verify full build

pnpm turbo run dev --filter=@openwork/desktop

```

**Critical**: Always run `pnpm install` at the monorepo root, never in individual package directories. The [`pnpm-workspace.yaml`](https://github.com/different-ai/openwork/blob/main/pnpm-workspace.yaml) defines workspace boundaries; violating this causes phantom dependency resolution.

## Per-Session Agent Selection Drift

A subtle configuration issue occurs when the **per-session agent selector** fails to persist across window reloads. This relates to how [`apps/desktop/src/electron/main.ts`](https://github.com/different-ai/openwork/blob/main/apps/desktop/src/electron/main.ts) serializes session state to the profile's [`session.json`](https://github.com/different-ai/openwork/blob/main/session.json).

Ensure your dev profile has write permissions:

```bash

# Check profile directory permissions

ls -la ~/.openwork/profiles/$OPENWORK_DEV_PROFILE/

# Reset session state if corrupted

rm ~/.openwork/profiles/$OPENWORK_DEV_PROFILE/session.json

```

## Summary

- **Profile locks**: Delete `~/.openwork/dev-profile-lock` and use unique `OPENWORK_DEV_PROFILE` values to isolate development contexts
- **Windows blocking**: Launch via `cmd /c` or detached process to prevent STDIO deadlock
- **Browser UI**: Register `contextmenu` listeners in renderer and preload; disable passkey auto-prompt if needed
- **Loading states**: Always place `setLoading(false)` in `finally` blocks of async task runners
- **Dependencies**: Run `pnpm install` exclusively from repository root after any version bumps

## Frequently Asked Questions

### Why does OpenWork hang on startup with "profile locked" error?

The previous Electron instance did not shut down cleanly, leaving a stale lock file in `~/.openwork/dev-profile-lock`. Remove this file or specify a new `OPENWORK_DEV_PROFILE` environment variable to force creation of a fresh lock and CDP port allocation.

### How do I fix right-click menus in the embedded browser?

The in-app browser requires explicit `contextmenu` event handling. Register a listener in your renderer process that prevents the default chromium menu and communicates with the main process via `contextBridge` to display native menus. Ensure `contextIsolation` is properly configured in the preload script.

### What causes the loading spinner to stay active after tasks complete?

The async task runner in [`loading.tsx`](https://github.com/different-ai/openwork/blob/main/loading.tsx) lacks guaranteed cleanup. Move `setLoading(false)` into a `finally` block so it executes regardless of whether the task succeeds, fails, or throws—matching the pattern shown in the fixed implementation above.

### How should I update dependencies in the OpenWork monorepo?

Always run `pnpm install` from the repository root, never in individual package directories. This ensures [`pnpm-lock.yaml`](https://github.com/different-ai/openwork/blob/main/pnpm-lock.yaml) stays synchronized across all workspaces defined in [`pnpm-workspace.yaml`](https://github.com/different-ai/openwork/blob/main/pnpm-workspace.yaml). After major bumps, clear `node_modules` and the lock file entirely before reinstalling.