can1357/oh-my-pi · error · ToolError

attach requires pid or port

Error message

attach requires pid or port

What it means

The attach action needs a target: a `pid`, a `port`, or — as a permissive fallback — at least an `adapter` name (some adapters can discover targets themselves). If all three are undefined, execute throws before selecting an adapter because there is no way to identify the process or endpoint to attach to.

Source

Thrown at packages/coding-agent/src/tools/debug.ts:768

					throw new ToolError(
						`No debugger adapter available. Installed adapters: ${getConfiguredAdapters(commandCwd)}`,
					);
				}
				const { adapter } = selection;
				validateLaunchProgram(program, commandCwd, programKind, adapter);
				const extraLaunchArguments = resolveLaunchOverrides(adapter, program, programKind);
				const snapshot = await dapSessionManager.launch(
					{ adapter, program, args: params.args, cwd: commandCwd, extraLaunchArguments },
					combinedSignal,
					timeoutSec * 1000,
				);
				details.snapshot = snapshot;
				details.adapter = adapter.name;
				return result.text(formatSessionSnapshot(snapshot).join("\n")).done();
			}
			case "attach": {
				if (params.pid === undefined && params.port === undefined && !params.adapter) {
					throw new ToolError("attach requires pid or port");
				}
				const commandCwd = params.cwd ? resolveToCwd(params.cwd, this.session.cwd) : this.session.cwd;
				const adapter = selectAttachAdapter(commandCwd, params.adapter, params.port);
				if (!adapter) {
					if (params.adapter) {
						const command = getAdapterConfigs(commandCwd)[params.adapter]?.command ?? params.adapter;
						throw new ToolError(formatAdapterUnavailable(params.adapter, command, commandCwd));
					}
					throw new ToolError(
						`No debugger adapter available. Installed adapters: ${getConfiguredAdapters(commandCwd)}`,
					);
				}
				const snapshot = await dapSessionManager.attach(
					{ adapter, cwd: commandCwd, pid: params.pid, port: params.port, host: params.host },
					combinedSignal,
					timeoutSec * 1000,
				);
				details.snapshot = snapshot;

View on GitHub (pinned to 9690622007)

Solutions

  1. Pass the target process id: `pid: <pid>`.
  2. Or pass the debug adapter's listening `port` for attach-over-socket.
  3. Or supply `adapter` if the adapter supports target discovery without an explicit pid/port.

Example fix

// before
{ "action": "attach" }
// after
{ "action": "attach", "pid": 12345 }
Defensive patterns

Strategy: validation

Validate before calling

function assertAttachArgs(p: { pid?: number; port?: number; adapter?: string }): void {
  if (p.pid === undefined && p.port === undefined && !p.adapter) {
    throw new Error("attach needs pid, port, or adapter");
  }
}

Type guard

function hasAttachTarget(p: { pid?: number; port?: number; adapter?: string }): boolean {
  return p.pid !== undefined || p.port !== undefined || p.adapter !== undefined;
}

Try / catch

try {
  return await debugTool({ action: "attach", ...args });
} catch (e) {
  if (String(e).includes("attach requires pid or port")) {
    throw new Error("resolve a target pid or debug port before attaching");
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling the debug tool with action="attach" and omitting pid, port, and adapter entirely.

Common situations: Confusing attach with launch semantics; intending to use adapter-based auto-discovery but forgetting the adapter name; an automation script that drops optional fields when they are actually required together.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31). Data as JSON: /api/errors/1bf447fc730ba801. Report an issue: GitHub.