can1357/oh-my-pi · error · ToolError
Target id unavailable from CDP target info
Error message
Target id unavailable from CDP target info
What it means
The tab-supervisor resolves a Puppeteer Target's id by first reading the private `_targetId` field, then falling back to opening a temporary CDP session and calling `Target.getTargetInfo`. This ToolError is thrown when the CDP response arrives but contains no `targetInfo.targetId`, meaning the browser could not identify the target.
Source
Thrown at packages/coding-agent/src/tools/browser/tab-supervisor.ts:1051
}
function expandBrowserScreenshotDir(session: ToolSession): string | undefined {
const value = session.settings.get("browser.screenshotDir") as string | undefined;
return value ? expandPath(value) : undefined;
}
async function targetIdForPage(page: Page): Promise<string> {
return await targetIdForTarget(page.target());
}
async function targetIdForTarget(target: Target): Promise<string> {
const raw = target as unknown as { _targetId?: unknown };
if (typeof raw._targetId === "string") return raw._targetId;
const session = await target.createCDPSession();
try {
const info = (await session.send("Target.getTargetInfo")) as { targetInfo?: { targetId?: string } };
if (info.targetInfo?.targetId) return info.targetInfo.targetId;
throw new ToolError("Target id unavailable from CDP target info");
} finally {
await session.detach().catch(() => undefined);
}
}
function errorFromPayload(payload: RunErrorPayload): Error {
const error = payload.recoverTab
? new RecoverableWorkerError(payload.message)
: payload.isAbort
? new ToolAbortError()
: payload.isToolError
? new ToolError(payload.message)
: new Error(payload.message);
error.name = payload.name;
if (payload.stack) error.stack = payload.stack;
return error;
}
View on GitHub (pinned to 9690622007)
Solutions
- Retry the operation after a short delay — the target is likely closing; re-enumerate targets via browser.targets() and pick one that still reports a page.
- Check the puppeteer version: if `_targetId` was removed/renamed upstream, upgrade or pin puppeteer so the fast path in tab-supervisor works.
- Filter targets before resolving ids (skip `target.type() !== 'page'` targets) so CDP is only queried for real page targets.
- Wrap the call in try/catch and treat it as 'target gone': remove the tab from supervision instead of failing the whole tool call.
Example fix
// before
const info = (await session.send("Target.getTargetInfo")) as { targetInfo?: { targetId?: string } };
if (info.targetInfo?.targetId) return info.targetInfo.targetId;
throw new ToolError("Target id unavailable from CDP target info");
// after
const info = (await session.send("Target.getTargetInfo").catch(() => undefined)) as
| { targetInfo?: { targetId?: string } }
| undefined;
if (info?.targetInfo?.targetId) return info.targetInfo.targetId;
return null; // caller treats null as 'target vanished' and re-lists targets Defensive patterns
Strategy: try-catch
Validate before calling
// before calling
const target = browser.targets().find(t => t.type() === "page");
if (!target) throw new Error("no live page target available"); Try / catch
try {
const id = await resolveTargetId(target);
} catch (err) {
if (err instanceof ToolError && err.message.includes("Target id unavailable")) {
return reenumerateTargets(); // target was closing
}
throw err;
} Prevention
- Only resolve ids for targets with type() === 'page'
- Avoid resolving ids during teardown/navigation races; add small delays or retry
- Keep puppeteer updated so the _targetId fast path works
When it happens
Trigger: Called on a Target whose CDP session connects but returns an empty/malformed `Target.getTargetInfo` response — typically a target that is closing, already closed, or of a type that never exposes a page target id (e.g. a service-worker or browser-level target).
Common situations: Racing a tab close while tab bookkeeping runs; connecting to a flaky/remote Chromium via CDP that drops target info; puppeteer internals changed so `_targetId` is absent and the CDP fallback hits an already-detached target.
Related errors
- Target id unavailable from CDP target info
- Connected to ${cdpUrl} but puppeteer.connect failed: ${(err
- Created headless target ${targetId} did not expose a page
- Target ${payload.targetId} is no longer available on the att
- Target ${targetId} is no longer available on the attached br
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/55174df07d3b4860.
Report an issue: GitHub.