{"record":{"id":"d3d4e686f7314ded","repo":"can1357/oh-my-pi","slug":"unsupported-selector-action-action","errorCode":null,"errorMessage":"Unsupported selector action ${action}","messagePattern":"Unsupported selector action (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/coding-agent/src/tools/browser/cmux/cmux-tab.ts","lineNumber":974,"sourceCode":"\t\t\t\t\t}\n\t\t\t\t\tinputEvent(element);\n\t\t\t\t\treturn selected;\n\t\t\t\t}\n\t\t\t\tcase \"uploadFile\": {\n\t\t\t\t\tif (element.tagName !== \"INPUT\" || element.type !== \"file\") {\n\t\t\t\t\t\tthrow new Error(\"tab.uploadFile() requires an <input type=file> element\");\n\t\t\t\t\t}\n\t\t\t\t\tconst transfer = new DataTransfer();\n\t\t\t\t\tfor (const file of args.files || []) {\n\t\t\t\t\t\tconst bytes = Uint8Array.from(atob(file.data), char => char.charCodeAt(0));\n\t\t\t\t\t\ttransfer.items.add(new File([bytes], file.name, { type: file.type || \"application/octet-stream\" }));\n\t\t\t\t\t}\n\t\t\t\t\telement.files = transfer.files;\n\t\t\t\t\tinputEvent(element);\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\t\t\tthrow new Error(\"Unsupported selector action \" + action);\n\t\t})()`;\n\t\tconst result = (await this.#request(\"browser.eval\", { script }, this.#runContext?.timeoutMs)) as CmuxEvalResult;\n\t\treturn result.value as TResult;\n\t}\n\n\tasync #waitForSelector(selector: string, timeoutMs: number): Promise<void> {\n\t\tconst signal = this.#runContext?.signal;\n\t\tconst spec = this.#selectorSpec(selector);\n\t\tconst nativeSelector = this.#nativeSelector(spec);\n\t\tif (nativeSelector) {\n\t\t\tawait this.#request(\"browser.wait\", { selector: nativeSelector, timeout_ms: timeoutMs }, timeoutMs, signal);\n\t\t\treturn;\n\t\t}\n\t\tconst deadline = Date.now() + timeoutMs;\n\t\twhile (Date.now() <= deadline) {\n\t\t\tif (await this.#selectorExists(spec)) return;\n\t\t\tawait untilAborted(signal, () => Bun.sleep(100));\n\t\t}","sourceCodeStart":956,"sourceCodeEnd":992,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/coding-agent/src/tools/browser/cmux/cmux-tab.ts#L956-L992","documentation":"The per-element eval script dispatches on an `action` string via a switch (click, setValue, scrollIntoView, select, uploadFile, ...). If the action name falls through every case, the script throws `Unsupported selector action <action>`. This guards against typos and actions not yet implemented in the in-page bridge.","triggerScenarios":"Passing a misspelled or unsupported action name into the tab's selector-action API (e.g. 'setvalue', 'check', 'hover'), or calling a newer action against an older cmux daemon whose eval script lacks that case.","commonSituations":"Version mismatch between client wrapper and daemon (action added upstream, daemon outdated); typo in a dynamically-built action string; refactoring renamed an action constant on one side only.","solutions":["Check the action string against the implemented switch cases in cmux-tab.ts (click, setValue, scrollIntoView, select, uploadFile, etc.) and fix the typo/casing.","Update the cmux daemon/browser bundle so client and in-page bridge versions match.","If the action is genuinely missing, implement a new case in the eval script's switch or compose it from existing actions."],"exampleFix":"// before\ntab.action(el, 'setvalue', 'hello');\n// after\ntab.action(el, 'setValue', 'hello'); // exact camelCase action name","handlingStrategy":"validation","validationCode":"const SUPPORTED_ACTIONS = ['click','setValue','scrollIntoView','select','uploadFile'] as const;\nif (!SUPPORTED_ACTIONS.includes(action as typeof SUPPORTED_ACTIONS[number]))\n  throw new Error(`unknown selector action: ${action}`);","typeGuard":"type SelectorAction = typeof SUPPORTED_ACTIONS[number];\nfunction isSelectorAction(a: string): a is SelectorAction { return (SUPPORTED_ACTIONS as readonly string[]).includes(a); }","tryCatchPattern":null,"preventionTips":["Use a string-literal union type for action names so typos fail at compile time.","Keep client action constants and the in-page switch in sync; bump daemon and client together.","Never build action names dynamically by concatenation."],"tags":["browser-automation","invalid-argument","api-mismatch"],"backgroundTag":"unsupported-action-name","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}