# How to Debug Issues with the Copilot SDK Integration: 9 Proven Methods

> Debug Copilot SDK integration issues effectively. Expose connection failures authentication errors and CLI process crashes with 9 proven methods. Improve your integration now.

- Repository: [GitHub/copilot-sdk](https://github.com/github/copilot-sdk)
- Tags: how-to-guide
- Published: 2026-07-20

---

**Enable `logLevel: "debug"` when instantiating the `CopilotClient` and subscribe to `stateChange` and `error` events to expose connection failures, authentication errors, and CLI process crashes during Copilot SDK integration.**

The GitHub Copilot SDK acts as a JSON-RPC client that communicates with the Copilot CLI over stdio or TCP transports. When integrations fail—whether due to missing binaries, authentication token issues, or invalid tool schemas—the most actionable diagnostics come from SDK logs, connection state events, and CLI process health checks. This guide draws from the official `github/copilot-sdk` repository to provide concrete solutions for resolving the most common failure modes.

## Enable Verbose Logging in the SDK Client

The SDK’s logger only emits diagnostic output when `logLevel` is set to `"debug"` or `"all"`. In [`nodejs/src/client.ts`](https://github.com/github/copilot-sdk/blob/main/nodejs/src/client.ts) (lines 55-66), the `logDebug` method checks this configuration before writing to stderr.

Initialize the client with verbose logging enabled:

```typescript
import { CopilotClient } from "@github/copilot-sdk";

const client = new CopilotClient({
  logLevel: "debug",  // Enables debug output
});

```

To persist logs to a custom directory instead of stderr, pass `--log-dir` via the `cliArgs` option as documented in [`docs/troubleshooting/debugging.md`](https://github.com/github/copilot-sdk/blob/main/docs/troubleshooting/debugging.md) (lines 15-20):

```typescript
const client = new CopilotClient({
  logLevel: "debug",
  cliArgs: ["--log-dir", "/tmp/copilot-logs"],
});

```

## Verify CLI Binary Availability

The SDK spawns the Copilot CLI as a subprocess unless you explicitly provide an external server connection. Connection failures often manifest as `Error: spawn … ENOENT` when the binary cannot be found in the system PATH.

The client defaults to stdio transport when no connection object is supplied, as implemented in [`nodejs/src/client.ts`](https://github.com/github/copilot-sdk/blob/main/nodejs/src/client.ts) (lines 26-30). To resolve spawn errors, provide an absolute path via the `cliPath` option:

```typescript
const client = new CopilotClient({
  cliPath: "/usr/local/bin/copilot",  // Absolute path to executable
});

```

According to [`docs/troubleshooting/debugging.md`](https://github.com/github/copilot-sdk/blob/main/docs/troubleshooting/debugging.md) (lines 12-16), always verify the CLI version matches your SDK version by running `copilot --version` before integration.

## Resolve Authentication and Token Errors

RPC calls fail with "Not authenticated" when the SDK cannot obtain a valid GitHub token. The client supports two authentication sources: environment variables (`GITHUB_TOKEN` or `COPILOT_GITHUB_TOKEN`) or the explicit `gitHubToken` constructor option.

Pass the token directly when instantiating the client:

```typescript
const client = new CopilotClient({
  gitHubToken: process.env.GITHUB_TOKEN,
});

```

When connecting to an external CLI server using `RuntimeConnection.forUri`, the server handles authentication independently. The SDK enforces that you **must not** provide a token in this mode, throwing a configuration error if both are present, as seen in [`nodejs/src/client.ts`](https://github.com/github/copilot-sdk/blob/main/nodejs/src/client.ts) (lines 31-38).

## Diagnose Connection Mode Failures

The SDK supports **stdio** (subprocess) and **TCP** (socket) transports. The chosen mode is stored in the `RuntimeConnection` object during client construction.

Monitor connection health by subscribing to state events:

```typescript
client.on("stateChange", (state) => {
  console.error("Connection state:", state);
});
client.on("error", (err) => {
  console.error("SDK error:", err);
});

```

To isolate transport-level issues, manually run the CLI in server mode to verify it starts correctly:

```bash
copilot --server --stdio

```

This test, recommended in [`docs/troubleshooting/debugging.md`](https://github.com/github/copilot-sdk/blob/main/docs/troubleshooting/debugging.md) (lines 45-48), confirms the binary executes without crashing before the SDK attempts to manage the process.

## Handle Session Lifecycle Correctly

A common pitfall involves calling methods on a session after it has been disconnected. The SDK throws "Session not found" errors when you interact with dead sessions.

Always guard against this pattern:

```typescript
await session.disconnect();
// Do not call session methods after this point

```

You can audit active sessions by calling `client.listSessions()` to confirm valid session IDs before operations, as documented in [`docs/troubleshooting/debugging.md`](https://github.com/github/copilot-sdk/blob/main/docs/troubleshooting/debugging.md) (lines 33-37).

## Debug Tool Execution Errors

When custom tools fail silently or return errors, verify three implementation details:

1. **Registration**: Ensure the tool is passed in the `tools` array during `createSession()`
2. **Schema validation**: Confirm the tool’s JSON Schema includes required `type` fields and correct property definitions
3. **Return values**: Verify handlers return JSON-serializable objects without `undefined` or circular references

Subscribe to tool-specific error events to capture hidden failures:

```typescript
session.on("tool.execution_error", (e) => {
  console.error("Tool error:", e.data);
});

```

These requirements are detailed in [`docs/troubleshooting/debugging.md`](https://github.com/github/copilot-sdk/blob/main/docs/troubleshooting/debugging.md) (lines 48-73).

## MCP Server Integration Checks

When using a Model Context Protocol (MCP) server as a custom LLM backend, verify the server binary runs independently, responds to `initialize` requests, and has correctly enabled tools. The repository provides a dedicated checklist in [`docs/troubleshooting/mcp-debugging.md`](https://github.com/github/copilot-sdk/blob/main/docs/troubleshooting/mcp-debugging.md) for validating these external dependencies.

## Platform-Specific Debugging Tips

Path and permission issues vary by operating system:

- **Windows**: Use absolute paths with escaped backslashes (`C:\\Program Files\\GitHub\\copilot.exe`) and ensure the executable includes the `.exe` extension
- **macOS**: GUI applications may not inherit shell PATH variables; always provide the full `cliPath` in client options
- **Linux**: Confirm the binary is executable (`chmod +x`) and required shared libraries are present (`ldd /path/to/copilot`)

These platform considerations are enumerated in [`docs/troubleshooting/debugging.md`](https://github.com/github/copilot-sdk/blob/main/docs/troubleshooting/debugging.md) (lines 92-106).

## Summary

- **Enable debug logging** by setting `logLevel: "debug"` and optionally specify `--log-dir` via `cliArgs` to capture verbose output
- **Verify CLI paths** using the `cliPath` option to resolve `ENOENT` spawn errors, and confirm version compatibility with `copilot --version`
- **Handle authentication** by providing `gitHubToken` for stdio mode, but omit tokens when using `RuntimeConnection.forUri` external servers
- **Monitor connection state** via `stateChange` and `error` events, and test the CLI standalone with `copilot --server --stdio`
- **Manage session lifecycle** by avoiding method calls after `session.disconnect()` and using `client.listSessions()` to verify active sessions
- **Validate custom tools** against JSON Schema requirements and listen for `tool.execution_error` events to surface handler failures

## Frequently Asked Questions

### Why does my Copilot SDK client throw "spawn ENOENT" errors?

This error indicates the SDK cannot locate the Copilot CLI binary in the system PATH. Provide an absolute path via the `cliPath` option in `CopilotClientOptions`, or ensure the `copilot` executable is available in a directory listed in your environment PATH variable.

### How do I provide authentication tokens to the CopilotClient?

Pass the token using the `gitHubToken` constructor option, or set the `GITHUB_TOKEN` or `COPILOT_GITHUB_TOKEN` environment variable before starting your application. When connecting to an external server via `RuntimeConnection.forUri`, do not provide a token as the server manages its own authentication.

### What causes "Session not found" errors in the Copilot SDK?

This error occurs when you attempt to call methods on a session after invoking `session.disconnect()`. The SDK explicitly invalidates the session ID after disconnection. Always verify active sessions using `client.listSessions()` before operations, and create new sessions rather than reusing disconnected ones.

### Why are my custom tools returning execution errors?

Custom tools must return JSON-serializable values—avoid `undefined`, functions, or circular objects. Ensure your tool schema uses valid JSON Schema syntax with correct `type` declarations, and register the tool in the `tools` array when calling `createSession()`. Subscribe to `tool.execution_error` events to capture runtime handler exceptions.