can1357/oh-my-pi · error · ToolError

Invalid selector ':${internalTarget.sel}' on '${internalTarg

Error message

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

What it means

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.

Source

Thrown at packages/coding-agent/src/tools/read.ts:1164

				});
			}
			return executeReadUrl(this.session, { path: parsedUrlTarget.path, raw: urlRaw }, signal);
		}

		// Handle native OMP URLs and custom-scheme resources advertised by MCP servers.
		const internalRouter = InternalUrlRouter.instance();
		const delimitedInternalResult = internalRouter.canResolve(readPath)
			? await this.#tryReadDelimitedPaths(readPath, signal, entry => internalRouter.canResolve(entry))
			: null;
		if (delimitedInternalResult) return delimitedInternalResult;

		// Peel malformed selectors through the internal-URL-aware parser before routing.
		let promotedSelector: string | undefined;
		if (internalRouter.canResolve(readPath)) {
			const internalTarget = splitInternalUrlSel(readPath);
			const parsed = parseSel(internalTarget.sel);
			if (internalTarget.sel !== undefined && parsed.kind === "none") {
				throw new ToolError(
					`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).`,
				);
			}
			const urlMeta = parseInternalUrl(internalTarget.path);
			const scheme = urlMeta.protocol.replace(/:$/, "").toLowerCase();
			const imageSelectorMessage = "The ':img' selector only supports local .svg and .svgz files.";
			if (parsed.kind === "image" && scheme !== "local") {
				throw new ToolError(imageSelectorMessage);
			}
			if (scheme === "local") {
				const localFile = await resolveLocalUrlToFile(urlMeta, {
					cwd: this.session.cwd,
					settings: this.session.settings,
					signal,
					localProtocolOptions: this.session.localProtocolOptions,
					skills: this.session.skills,
				});
				if (localFile) {

View on GitHub (pinned to 9690622007)

Solutions

  1. 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.
  2. 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.
  3. Re-check the exact line numbers/ranges wanted and re-issue the read with a valid comma-separated list (e.g. ':10-20,40').

Example fix

// before
read("src/app.ts:50..60")
// after
read("src/app.ts:50-60")
Defensive patterns

Strategy: validation

Validate before calling

const SEL_RE = /^(\d+(-\d+|\+\d+|-)?)(,\d+(-\d+|\+\d+|-)?)*|raw(:\d+-\d+)?|img$/;
if (sel !== undefined && !SEL_RE.test(sel)) throw new Error(`Bad selector ':${sel}'`);

Type guard

function isValidSelector(sel) { return sel === undefined || /^(\d+(-\d+|\+\d+|-)?)(,\d+(-\d+|\+\d+|-)?)*$|^raw(:\d+-\d+)?$|^img$/.test(sel); }

Try / catch

try { await read(path) } catch (e) { if (e instanceof ToolError && e.message.startsWith('Invalid selector')) { /* retry without selector or fix syntax */ } else throw e; }

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31). Data as JSON: /api/errors/1707e8656d52ebbf. Report an issue: GitHub.