{"record":{"id":"df69c3241c379fbe","repo":"openclaw/openclaw","slug":"ambiguous-browser-tab-reference-df69c3","errorCode":null,"errorMessage":"ambiguous browser tab reference","messagePattern":"ambiguous browser tab reference","errorType":"exception","errorClass":"BrowserTargetAmbiguousError","httpStatus":409,"severity":"warning","filePath":"extensions/browser/src/browser/server-context.tab-ops.ts","lineNumber":486,"sourceCode":"          type: created.type,\n        },\n        opts,\n      ),\n      { ...opts, label: normalizedLabel },\n    );\n  };\n\n  const labelTab = async (\n    targetId: string,\n    label: string,\n    options?: BrowserOperationOptions,\n  ): Promise<BrowserTab> => {\n    const normalizedLabel = normalizeTabLabel(label);\n    const tabs = await listTabs(options);\n    const resolved = resolveTargetIdFromTabs(targetId, tabs);\n    if (!resolved.ok) {\n      if (resolved.reason === \"ambiguous\") {\n        throw new BrowserTargetAmbiguousError();\n      }\n      throw new BrowserTabNotFoundError({ input: targetId });\n    }\n    const tab = tabs.find((candidate) => candidate.targetId === resolved.targetId);\n    if (!tab) {\n      throw new BrowserTabNotFoundError({ input: targetId });\n    }\n    return assignTabAlias({ profileState: runtime, tab, label: normalizedLabel });\n  };\n\n  return {\n    listTabs,\n    openTab,\n    labelTab,\n  };\n}\n","sourceCodeStart":468,"sourceCodeEnd":503,"githubUrl":"https://github.com/openclaw/openclaw/blob/01804a75319da4b69c9ab98ceaa30477e22b8c0b/extensions/browser/src/browser/server-context.tab-ops.ts#L468-L503","documentation":"BrowserTargetAmbiguousError (HTTP 409) thrown inside labelTab when resolveTargetIdFromTabs returns {ok:false, reason:'ambiguous'}. The supplied targetId/label/prefix matched more than one live tab across the exact-match namespace (targetId, suggestedTargetId, tabId, label) or the raw target-id prefix namespace. The runtime fails closed rather than guessing which tab to relabel.","triggerScenarios":"labelTab(targetId, label) is called with an input whose exact-match set resolves to >1 distinct targetId, or whose lowercased prefix matches >1 targetId. Examples: two tabs share a label alias; a short prefix like 'AB' matches multiple targetIds; a tabId collides with a raw targetId.","commonSituations":"User passes a short/ambiguous prefix; a label was reused across tabs; stale aliases survived a tab restart. The cross-namespace collision guard also fires when a friendly id and a raw id both happen to match.","solutions":["Pass the full raw targetId (or a longer unique prefix) returned from action=tabs.","Use suggestedTargetId or tabId from the tabs list for an exact, unique reference.","Rename/deduplicate labels so only one tab carries the alias you intend to target.","Call listTabs first, inspect matches, and pass a value that resolves uniquely."],"exampleFix":"// before\nawait labelTab(\"docs\", \"primary\"); // multiple tabs labeled/starting 'docs'\n\n// after\nconst tabs = await listTabs();\nconst exact = tabs.find(t => t.tabId === \"t7\");\nawait labelTab(exact.targetId, \"primary\");","handlingStrategy":"validation","validationCode":"import { resolveTargetIdFromTabs } from \"./target-id.js\";\n\nconst tabs = await listTabs();\nconst r = resolveTargetIdFromTabs(input, tabs);\nif (!r.ok) {\n  if (r.reason === \"ambiguous\") {\n    // pick a longer/unique prefix or an exact tabId, then retry\n  }\n}","typeGuard":null,"tryCatchPattern":"try { await labelTab(input, label); }\ncatch (err) {\n  if (err.status === 409 && /ambiguous/.test(err.message)) {\n    // re-list, disambiguate by passing full targetId or tabId\n  } else throw err;\n}","preventionTips":["Always pass the full targetId (or a unique tabId) returned from listTabs.","Keep labels unique to avoid exact-match ambiguity.","Resolve references via resolveTargetIdFromTabs before mutating."],"tags":["browser","tab-selection","ambiguous","label"],"backgroundTag":null,"analyzedSha":"01804a75319da4b69c9ab98ceaa30477e22b8c0b","analyzedAt":"2026-08-12T04:37:58.197Z","contentChangedAt":"2026-08-12T04:37:58.197Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}