How to Debug Issues in OpenWork: A Complete Troubleshooting Guide
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 that outputs JSON-structured log lines with severity levels.
Set the environment variable before launching the application:
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:
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:
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, with configuration managed in 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:
-
Start the proxy (launched automatically with
pnpm dev). -
Access the endpoint through the proxy tunnel:
curl "http://localhost:3010/debug-proxy/debug-access-key-1234/v1/mcp/token?token=secret" -
Configure fault scenarios by editing
ee/apps/diagnostics/src/connect-debug-proxy-scenarios.tsto return specific error codes, latency spikes, or malformed JSON. -
Observe rewritten responses in Chrome DevTools or via the observability logs, which will contain entries like:
{"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 exposes a debugDesktopBootstrapConfig field that captures the initial arguments and results.
To expose this data, inject the following in the main process:
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 that automates CDP attachment, screenshot capture, and UI state assertions.
Execute the full diagnostic suite:
pnpm test:e2e
The runner automatically connects to the CDP port advertised in the dev banner and generates a 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:
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=debugto emit structured JSON traces fromee/packages/utils/src/observability.ts. - Attach Chrome DevTools to the CDP endpoint (configured via
OPENWORK_ELECTRON_REMOTE_DEBUG_PORT) using the helpers inevals/runner/cdp.ts. - Use the Connect-Debug-Proxy (implemented in
ee/apps/diagnostics/src/connect-debug-proxy.ts) with the keydebug-access-key-1234to inject faults and inspect MCP network flows. - Inspect bootstrap state by logging
debugDesktopBootstrapConfigfrompackages/types/src/desktop-ipc.tsto verify Electron launch arguments. - Validate fixes by running
pnpm test:e2eto generate afraimz.htmlreport viaevals/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, 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 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. 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.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →