{"record":{"id":"1707e8656d52ebbf","repo":"can1357/oh-my-pi","slug":"invalid-selector-internaltarget-sel-on-in","errorCode":null,"errorMessage":"Invalid selector ':${internalTarget.sel}' on '${internalTarget.path}'. Use :N, :N-M, :N+K, :N- (open-ended), a comma-separated list of ranges, :raw, :img for SVG rendering, or a range combined w","messagePattern":"Invalid selector ':(.+?)' on '(.+?)'\\. Use :N, :N-M, :N\\+K, :N- \\(open-ended\\), a comma-separated list of ranges, :raw, :img for SVG rendering, or a range combined w","errorType":"exception","errorClass":"ToolError","httpStatus":null,"severity":"error","filePath":"packages/coding-agent/src/tools/read.ts","lineNumber":1164,"sourceCode":"\t\t\t\t});\n\t\t\t}\n\t\t\treturn executeReadUrl(this.session, { path: parsedUrlTarget.path, raw: urlRaw }, signal);\n\t\t}\n\n\t\t// Handle native OMP URLs and custom-scheme resources advertised by MCP servers.\n\t\tconst internalRouter = InternalUrlRouter.instance();\n\t\tconst delimitedInternalResult = internalRouter.canResolve(readPath)\n\t\t\t? await this.#tryReadDelimitedPaths(readPath, signal, entry => internalRouter.canResolve(entry))\n\t\t\t: null;\n\t\tif (delimitedInternalResult) return delimitedInternalResult;\n\n\t\t// Peel malformed selectors through the internal-URL-aware parser before routing.\n\t\tlet promotedSelector: string | undefined;\n\t\tif (internalRouter.canResolve(readPath)) {\n\t\t\tconst internalTarget = splitInternalUrlSel(readPath);\n\t\t\tconst parsed = parseSel(internalTarget.sel);\n\t\t\tif (internalTarget.sel !== undefined && parsed.kind === \"none\") {\n\t\t\t\tthrow new ToolError(\n\t\t\t\t\t`Invalid selector ':${internalTarget.sel}' on '${internalTarget.path}'. Use :N, :N-M, :N+K, :N- (open-ended), a comma-separated list of ranges, :raw, :img for SVG rendering, or a range combined with raw (e.g. :raw:50-100).`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tconst urlMeta = parseInternalUrl(internalTarget.path);\n\t\t\tconst scheme = urlMeta.protocol.replace(/:$/, \"\").toLowerCase();\n\t\t\tconst imageSelectorMessage = \"The ':img' selector only supports local .svg and .svgz files.\";\n\t\t\tif (parsed.kind === \"image\" && scheme !== \"local\") {\n\t\t\t\tthrow new ToolError(imageSelectorMessage);\n\t\t\t}\n\t\t\tif (scheme === \"local\") {\n\t\t\t\tconst localFile = await resolveLocalUrlToFile(urlMeta, {\n\t\t\t\t\tcwd: this.session.cwd,\n\t\t\t\t\tsettings: this.session.settings,\n\t\t\t\t\tsignal,\n\t\t\t\t\tlocalProtocolOptions: this.session.localProtocolOptions,\n\t\t\t\t\tskills: this.session.skills,\n\t\t\t\t});\n\t\t\t\tif (localFile) {","sourceCodeStart":1146,"sourceCodeEnd":1182,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/coding-agent/src/tools/read.ts#L1146-L1182","documentation":"ReadTool parses a `:selector` suffix attached to a file path or internal URL (line ranges, :raw, :img, etc.). If a selector is present but parseSel cannot classify it into any known form, the tool rejects the whole read with this usage message listing the accepted selector grammar.","triggerScenarios":"Calling the read tool with a path like 'file.ts:abc', 'dir/:10:11x', or any malformed suffix after a colon on a resolvable internal URL, where splitInternalUrlSel yields a non-empty selector that parseSel returns kind 'none' for.","commonSituations":"The agent or user hand-writes line selectors and typos them (e.g. ':50-' misspelled as ':50..60', stray text after a valid range), or a filename containing a colon is misinterpreted as carrying a selector.","solutions":["Correct the selector to one of the supported forms: :N, :N-M, :N+K, :N- (open-ended), comma-separated ranges, :raw, :img, or :raw:N-M.","If the path itself contains a colon and no selector is intended, quote or escape the path so the suffix is not parsed as a selector.","Re-check the exact line numbers/ranges wanted and re-issue the read with a valid comma-separated list (e.g. ':10-20,40')."],"exampleFix":"// before\nread(\"src/app.ts:50..60\")\n// after\nread(\"src/app.ts:50-60\")","handlingStrategy":"validation","validationCode":"const SEL_RE = /^(\\d+(-\\d+|\\+\\d+|-)?)(,\\d+(-\\d+|\\+\\d+|-)?)*|raw(:\\d+-\\d+)?|img$/;\nif (sel !== undefined && !SEL_RE.test(sel)) throw new Error(`Bad selector ':${sel}'`);","typeGuard":"function isValidSelector(sel) { return sel === undefined || /^(\\d+(-\\d+|\\+\\d+|-)?)(,\\d+(-\\d+|\\+\\d+|-)?)*$|^raw(:\\d+-\\d+)?$|^img$/.test(sel); }","tryCatchPattern":"try { await read(path) } catch (e) { if (e instanceof ToolError && e.message.startsWith('Invalid selector')) { /* retry without selector or fix syntax */ } else throw e; }","preventionTips":["Only emit selectors matching the documented grammar (:N, :N-M, :N+K, :N-, comma lists, :raw, :img)","Escape or quote file paths that literally contain colons","Reuse a shared selector-builder helper instead of string concatenation"],"tags":["read-tool","selector-syntax","validation"],"backgroundTag":"invalid-line-selector","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}