{"record":{"id":"98d9ffdcf1a1c6f9","repo":"jackwener/OpenCLI","slug":"resolution-message","errorCode":null,"errorMessage":"${resolution.message}","messagePattern":"\\$\\{resolution\\.message\\}","errorType":"error_code","errorClass":"TargetError","httpStatus":null,"severity":"error","filePath":"src/cli.ts","lineNumber":1026,"sourceCode":"  $ opencli browser work unbind\n`);\n  const originalBrowserDescription = browser.description();\n\n  /**\n   * Resolve a `<target>` (numeric ref or CSS selector) via the unified resolver.\n   * Returns the CSS match count so callers can propagate `matches_n` into the\n   * JSON envelope printed back to the agent.\n   */\n  async function resolveRef(\n    page: Awaited<ReturnType<typeof getBrowserPage>>,\n    ref: string,\n    opts: ResolveOptions = {},\n  ): Promise<{ matches_n: number; match_level: TargetMatchLevel }> {\n    const resolution = await page.evaluate(resolveTargetJs(ref, opts)) as\n      | { ok: true; matches_n: number; match_level: TargetMatchLevel }\n      | { ok: false; code: TargetErrorCode; message: string; hint: string; candidates?: string[]; matches_n?: number };\n    if (!resolution.ok) {\n      throw new TargetError({\n        code: resolution.code,\n        message: resolution.message,\n        hint: resolution.hint,\n        candidates: resolution.candidates,\n        matches_n: resolution.matches_n,\n      });\n    }\n    return { matches_n: resolution.matches_n, match_level: resolution.match_level };\n  }\n\n  /**\n   * Parse `--nth <n>` flag, returning the parsed 0-based index or a usage error.\n   * The surface mirrors `--depth` etc. in `browser get html --as json`: the flag\n   * is optional, must be a non-negative integer when present, and on failure we\n   * emit the structured error envelope rather than throwing past the command.\n   */\n  function parseNthFlag(raw: unknown): number | null | { error: string } {\n    if (raw === undefined || raw === null || raw === '') return null;","sourceCodeStart":1008,"sourceCodeEnd":1044,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/src/cli.ts#L1008-L1044","documentation":"When resolving a target reference inside the page (via injected JS), the in-page resolver can fail with a coded TargetError. This code re-raises the in-page failure as a TargetError carrying code, message, hint, candidates, and match count. The thrown message is exactly the resolver's resolution.message.","triggerScenarios":"page.evaluate(resolveTargetJs(ref, opts)) returns { ok:false, ... } — i.e. the target reference could not be resolved: no matching element, ambiguous matches, unsupported selector, etc., depending on the TargetErrorCode.","commonSituations":"Selector typo or element not present in DOM at evaluation time; ambiguous text/role refs matching multiple elements; iframe/shadow-DOM content the resolver cannot see; page navigated away before evaluation.","solutions":["Read resolution.hint and candidates in the full TargetError to see near-misses and tighten the ref","Wait for the element to exist (wait-for / polling) before resolving","Make the target ref unambiguous (use a more specific selector or index)","Retry after page load completes — transient DOM states cause resolution failures"],"exampleFix":"// before\nawait browser.click('button submit'); // ambiguous: two submit buttons\n// after\nawait browser.click('button submit [data-testid=checkout]');","handlingStrategy":"try-catch","validationCode":"// Pre-check the element exists before resolving the target\nconst exists = await page.$(selector);\nif (!exists) throw new Error(`Target not in DOM yet: ${ref}`);","typeGuard":"function isFailedResolution(r: unknown): r is { ok: false; code: string; message: string; hint: string; candidates?: string[] } {\n  return typeof r === 'object' && r !== null && (r as { ok?: unknown }).ok === false;\n}","tryCatchPattern":"try {\n  await browser.click(ref);\n} catch (e) {\n  if (e instanceof TargetError) {\n    console.error(`Target ${ref} failed (${e.code}): ${e.message}\\nHint: ${e.hint}`);\n    if (e.candidates?.length) console.error('Near matches:', e.candidates);\n  }\n  throw e;\n}","preventionTips":["Wait for the element/DOM to be ready before resolving targets","Use specific, unambiguous selectors or refs with an index when matches can be multiple","Log resolution.hint and candidates — they usually pinpoint the fix","Re-resolve after navigation; stale targets from a previous page fail resolution"],"tags":["browser","target-resolution","dom"],"backgroundTag":"target-resolution-failed","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}