{"record":{"id":"bb58194abe1adb1a","repo":"n8n-io/n8n","slug":"invalid-role-argument-cannot-start-with-g","errorCode":null,"errorMessage":"Invalid ${role}: argument cannot start with '-' (got: ${JSON.stringify(value.slice(0, 20))})","messagePattern":"Invalid (.+?): argument cannot start with '-' \\(got: (.+?)\\)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"packages/@n8n/mcp-browser/src/adapters/agent-browser.ts","lineNumber":142,"sourceCode":"\t\t}\n\t\tif (tab.active) return;\n\t\tawait this.run(['tab', tab.tabId]);\n\t\tfor (const t of this.tabCache) t.active = t.tabId === pageId;\n\t}\n\n\tprivate resolveTarget(target: ElementTarget): string {\n\t\tconst value =\n\t\t\t'ref' in target\n\t\t\t\t? target.ref.startsWith('@')\n\t\t\t\t\t? target.ref\n\t\t\t\t\t: `@${target.ref}`\n\t\t\t\t: target.selector;\n\t\treturn AgentBrowserAdapter.assertSafeArg(value, 'element target');\n\t}\n\n\tprivate static assertSafeArg(value: string, role: string): string {\n\t\tif (value.length > 1 && value.startsWith('-')) {\n\t\t\tthrow new Error(\n\t\t\t\t`Invalid ${role}: argument cannot start with '-' (got: ${JSON.stringify(value.slice(0, 20))})`,\n\t\t\t);\n\t\t}\n\t\treturn value;\n\t}\n\n\tprivate async runAction(args: string[]): Promise<void> {\n\t\tconst resp = await this.run(args);\n\t\tif (!resp.success) {\n\t\t\tthrow new Error(resp.error ?? 'agent-browser action failed');\n\t\t}\n\t}\n\n\tprivate async navResult(pageId: string): Promise<NavigateResult> {\n\t\tconst tabs = await this.refreshTabs();\n\t\tconst tab = tabs.find((t) => t.tabId === pageId);\n\t\treturn { title: tab?.title ?? '', url: tab?.url ?? '', status: 0 };\n\t}","sourceCodeStart":124,"sourceCodeEnd":160,"githubUrl":"https://github.com/n8n-io/n8n/blob/5ac6606e81f67bb9534255570cd4e86fd8101eee/packages/@n8n/mcp-browser/src/adapters/agent-browser.ts#L124-L160","documentation":"Thrown by AgentBrowserAdapter.assertSafeArg when a string argument (element target ref, selector, URL, key, or selector in wait) has length > 1 and starts with '-'. The guard exists because agent-browser's CLI scans ALL raw args for '--help'/'-h' before parsing, so any arg starting with '-' would be misinterpreted as a flag — a command-injection / arg-spoofing vector. The first 20 chars of the offending value are echoed in the error.","triggerScenarios":"Calling any adapter method that runs assertSafeArg with a value starting with '-': a CSS selector like '-webkit-foo', an aria ref that somehow starts with '-', a URL starting with '-' (malformed), or press() keys like '-Enter'. Also newPage(url) and navigate(url) which call assertSafeArg on the URL.","commonSituations":"A snapshot ref was malformed and starts with '-'; a custom CSS selector begins with a vendor prefix; the type() method already peels leading '-' chars but press/upload/scroll/newPage/navigate do not; a model emitted a selector starting with a dash.","solutions":["Rewrite the selector so it does not start with '-' — e.g. prefix with a tag or attribute selector: '[data-id=\"-foo\"]' instead of '-foo'.","For press(), pass key combinations without a leading dash; use 'Minus' for the '-' key itself if supported.","If the value legitimately starts with '-', route through type() which peels leading dashes into separate calls.","Sanitize model-emitted selectors before passing them to click/hover/scroll."],"exampleFix":"// before — selector starts with '-' (rejected)\nawait adapter.click(pageId, { selector: '-moz-binding' });\n\n// after — wrap so it no longer starts with '-'\nawait adapter.click(pageId, { selector: '[style*=\"-moz-binding\"]' });","handlingStrategy":"validation","validationCode":"function isSafeArg(value: string): boolean {\n  return !(value.length > 1 && value.startsWith('-'));\n}","typeGuard":"function isSafeAgentBrowserArg(value: string): boolean {\n  return value.length <= 1 || !value.startsWith('-');\n}","tryCatchPattern":null,"preventionTips":["Sanitize model-emitted selectors/refs to not start with '-' before passing to click/hover/press/newPage.","For values that legitimately start with '-', route through type() which peels leading dashes.","Wrap selectors starting with a vendor prefix in an attribute selector like [style*=\"-moz-...\"]."],"tags":["mcp-browser","agent-browser","security","argument-injection","validation"],"backgroundTag":null,"analyzedSha":"5ac6606e81f67bb9534255570cd4e86fd8101eee","analyzedAt":"2026-08-12T05:26:35.080Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}