# How to Debug Issues in OpenWork: A Complete Troubleshooting Guide

> Debug OpenWork issues effectively. Enable debug logging, attach Chrome DevTools, and use the Connect-Debug-Proxy for swift problem resolution in this comprehensive troubleshooting guide.

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

---

**Enable debug logging with `DEN_OBSERVABILITY_BACKEND=debug`, attach Chrome DevTools to the CDP port shown in the dev banner, and use the Connect-Debug-Proxy to intercept requests for rapid diagnosis.**

When working with the **different-ai/openwork** repository, knowing how to debug issues in OpenWork efficiently can save hours of frustration. This hybrid Electron and cloud application provides multiple layers of instrumentation, from structured logging to Chrome DevTools Protocol (CDP) integration. Whether you are troubleshooting a startup failure or a network request mismatch, the following techniques leverage the actual source code implementation to give you complete visibility into the runtime.

## Enable Structured Debug Logging

The first step in any debugging session is to enable verbose logging. OpenWork uses a centralized observability utility located in [`ee/packages/utils/src/observability.ts`](https://github.com/different-ai/openwork/blob/main/ee/packages/utils/src/observability.ts) that outputs JSON-structured log lines with severity levels.

Set the environment variable before launching the application:

```bash
export DEN_OBSERVABILITY_BACKEND=debug
pnpm dev

```

When this variable is set to `debug`, the logger emits entries containing `"level":"debug"` fields that trace the call chain through the desktop and cloud boundaries. You can filter these streams using `jq` or grep to isolate specific components, such as the bootstrap sequence or MCP token exchanges.

## Attach Chrome DevTools via CDP

OpenWork runs Electron with remote debugging enabled. After running `pnpm dev`, the terminal banner displays a CDP endpoint (e.g., `cdp=http://127.0.0.1:9223`). You can attach a Chrome instance to this port for live DOM and network inspection.

To connect programmatically, use the helper functions defined in [`evals/runner/cdp.ts`](https://github.com/different-ai/openwork/blob/main/evals/runner/cdp.ts):

```typescript
import { connect, debuggerUrlFor } from "./evals/runner/cdp.ts";

const client = await connect(debuggerUrlFor("http://127.0.0.1:9223", "renderer"));
const title = await client.send("Runtime.evaluate", { 
  expression: "document.title" 
});
console.log("Page title:", title.result.value);

```

If the CDP port is auto-assigned, explicitly set it to avoid confusion:

```bash
export OPENWORK_ELECTRON_REMOTE_DEBUG_PORT=9223

```

From DevTools, you can inspect the React component tree, view network requests, and execute `window.__OPENWORK__?.debugInfo?.()` in the console to dump internal state objects directly from the renderer process.

## Intercept Network Requests with the Connect-Debug-Proxy

For debugging API interactions without modifying backend code, OpenWork includes a fault-injection proxy. The implementation lives in [`ee/apps/diagnostics/src/connect-debug-proxy.ts`](https://github.com/different-ai/openwork/blob/main/ee/apps/diagnostics/src/connect-debug-proxy.ts), with configuration managed in [`ee/apps/diagnostics/src/connect-debug-proxy-config.ts`](https://github.com/different-ai/openwork/blob/main/ee/apps/diagnostics/src/connect-debug-proxy-config.ts).

The proxy activates when you include the access key `debug-access-key-1234` in the URL path or the header `x-connect-debug-proxy-key`. To use it:

1. Start the proxy (launched automatically with `pnpm dev`).
2. Access the endpoint through the proxy tunnel:

   ```bash
   curl "http://localhost:3010/debug-proxy/debug-access-key-1234/v1/mcp/token?token=secret"
   ```

3. Configure fault scenarios by editing [`ee/apps/diagnostics/src/connect-debug-proxy-scenarios.ts`](https://github.com/different-ai/openwork/blob/main/ee/apps/diagnostics/src/connect-debug-proxy-scenarios.ts) to return specific error codes, latency spikes, or malformed JSON.
4. Observe rewritten responses in Chrome DevTools or via the observability logs, which will contain entries like:

   ```json
   {"level":"debug","message":"debug proxy request","path":"/v1/mcp/token","scenario":"token-mint-fail"}
   ```

This approach lets you verify how the Electron frontend handles specific failure modes without relying on actual upstream outages.

## Inspect Electron Bootstrap Configuration

Startup failures—such as the window failing to open or immediate process crashes—often stem from malformed bootstrap arguments. The type definition in [`packages/types/src/desktop-ipc.ts`](https://github.com/different-ai/openwork/blob/main/packages/types/src/desktop-ipc.ts) exposes a `debugDesktopBootstrapConfig` field that captures the initial arguments and results.

To expose this data, inject the following in the main process:

```typescript
import { desktopIpc } from "@openwork/types";

desktopIpc.debugDesktopBootstrapConfig = { 
  args: process.argv, 
  result: null 
};

```

When `DEN_OBSERVABILITY_BACKEND=debug` is active, this object emits as a structured log line, allowing you to verify that critical flags like `--remote-debugging-port` are correctly passed from the dev container scripts to the Electron binary.

## Run Automated End-to-End Diagnostics

For reproducible bug verification, OpenWork provides a test harness in [`evals/runner/runner.ts`](https://github.com/different-ai/openwork/blob/main/evals/runner/runner.ts) that automates CDP attachment, screenshot capture, and UI state assertions.

Execute the full diagnostic suite:

```bash
pnpm test:e2e

```

The runner automatically connects to the CDP port advertised in the dev banner and generates a [`fraimz.html`](https://github.com/different-ai/openwork/blob/main/fraimz.html) report. This report displays each UI frame alongside assertion results, making it ideal for comparing before-and-after states when applying fixes. You can open the report immediately after the run completes:

```bash
open ./fraimz.html

```

## Resolve Common Debugging Pitfalls

| Symptom | Root Cause | Resolution |
|---------|------------|------------|
| **CDP port unreachable** | Electron started with `--remote-debugging-port=0` (auto-assign) | Export `OPENWORK_ELECTRON_REMOTE_DEBUG_PORT=9223` to force a static port |
| **Debug proxy returns 403 "upstream not allowed"** | Target host not in whitelist | Add the host to `CONNECT_DEBUG_PROXY_ALLOWED_UPSTREAMS` or disable checks for local development |
| **Missing debug log lines** | `DEN_OBSERVABILITY_BACKEND` set to `info` | Restart with `export DEN_OBSERVABILITY_BACKEND=debug` |
| **Duplicate CDP ports after crash** | Stale Electron process holding the port | Kill stray processes with `pkill -f remote-debugging-port` or restart the dev container |
| **macOS keychain hangs** | Profile using system keychain instead of mock | Set `OPENWORK_ELECTRON_USE_MOCK_KEYCHAIN=1` for isolated dev profiles |

## Summary

- **Enable debug logging** by setting `DEN_OBSERVABILITY_BACKEND=debug` to emit structured JSON traces from [`ee/packages/utils/src/observability.ts`](https://github.com/different-ai/openwork/blob/main/ee/packages/utils/src/observability.ts).
- **Attach Chrome DevTools** to the CDP endpoint (configured via `OPENWORK_ELECTRON_REMOTE_DEBUG_PORT`) using the helpers in [`evals/runner/cdp.ts`](https://github.com/different-ai/openwork/blob/main/evals/runner/cdp.ts).
- **Use the Connect-Debug-Proxy** (implemented in [`ee/apps/diagnostics/src/connect-debug-proxy.ts`](https://github.com/different-ai/openwork/blob/main/ee/apps/diagnostics/src/connect-debug-proxy.ts)) with the key `debug-access-key-1234` to inject faults and inspect MCP network flows.
- **Inspect bootstrap state** by logging `debugDesktopBootstrapConfig` from [`packages/types/src/desktop-ipc.ts`](https://github.com/different-ai/openwork/blob/main/packages/types/src/desktop-ipc.ts) to verify Electron launch arguments.
- **Validate fixes** by running `pnpm test:e2e` to generate a [`fraimz.html`](https://github.com/different-ai/openwork/blob/main/fraimz.html) report via [`evals/runner/runner.ts`](https://github.com/different-ai/openwork/blob/main/evals/runner/runner.ts).

## Frequently Asked Questions

### How do I enable debug mode in OpenWork?

Set the environment variable `DEN_OBSERVABILITY_BACKEND=debug` before running `pnpm dev`. This activates the structured logger in [`ee/packages/utils/src/observability.ts`](https://github.com/different-ai/openwork/blob/main/ee/packages/utils/src/observability.ts), causing the application to emit detailed debug-level JSON log lines that include trace context and timestamp data.

### What is the Connect-Debug-Proxy and when should I use it?

The Connect-Debug-Proxy is a fault-injection middleware implemented in [`ee/apps/diagnostics/src/connect-debug-proxy.ts`](https://github.com/different-ai/openwork/blob/main/ee/apps/diagnostics/src/connect-debug-proxy.ts) that intercepts HTTP requests between the Electron client and upstream services. You should use it when you need to simulate specific error responses (like 503s or timeouts) or modify request headers without changing production backend code, allowing you to test client-side error handling logic.

### Where can I find the Chrome DevTools debugging port for OpenWork?

The port is displayed in the terminal banner immediately after running `pnpm dev`, labeled as the CDP endpoint (e.g., `cdp=http://127.0.0.1:9223`). You can force a specific port by exporting `OPENWORK_ELECTRON_REMOTE_DEBUG_PORT=9223` before starting the dev server, ensuring consistency across restarts.

### How do I debug a startup failure where the Electron window never appears?

Inspect the `debugDesktopBootstrapConfig` object defined in [`packages/types/src/desktop-ipc.ts`](https://github.com/different-ai/openwork/blob/main/packages/types/src/desktop-ipc.ts). By assigning the current `process.argv` to this field and ensuring `DEN_OBSERVABILITY_BACKEND=debug` is set, the bootstrap arguments and any early exit results will print to the logs, revealing missing flags or profile lock conflicts that prevent window initialization.