can1357/oh-my-pi · error · ToolError

Cannot combine query extraction with line selectors

Error message

Cannot combine query extraction with line selectors

What it means

Query extraction (a ?q= parameter or pathname extraction on agent:// URLs) and line selectors (:N, ranges) are mutually exclusive ways to narrow content. ReadTool throws if both are present, since it cannot apply a line slice to an extraction result.

Source

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

		}
		if (scheme === "artifact") {
			return this.#readArtifactFile(urlMeta, parsedSel, signal);
		}

		// local:// files are real on-disk paths. Detect image files and emit a
		// decoded image block before the text-only resource contract UTF-8
		// decodes the binary into mojibake. The fast path returns null for
		// non-images, directories, listings, or any resolution failure, so the
		// text path below reproduces the router's not-found / symlink-escape
		// behavior unchanged.
		if (scheme === "local") {
			const imageResult = await this.#tryReadLocalImage(urlMeta, signal);
			if (imageResult) return imageResult;
		}

		// Reject line selectors when query extraction is used
		if (hasExtraction && parsedSel.kind !== "none" && parsedSel.kind !== "raw") {
			throw new ToolError("Cannot combine query extraction with line selectors");
		}

		// Resolve the internal URL
		const resource = await internalRouter.resolve(url, {
			cwd: this.session.cwd,
			settings: this.session.settings,
			signal,
			sessionFile: this.session.getSessionFile() ?? undefined,
			localProtocolOptions: this.session.localProtocolOptions,
			skills: this.session.skills,
			xd: {
				read: async name => {
					if (name === REPORT_ISSUE_DEVICE_NAME) return reportIssueDeviceUsage();
					if (name && isResolutionDeviceName(name)) return resolutionDeviceUsage(name);
					const xdev = this.session.xdev;
					if (!xdev) throw new ToolError("xd:// is not mounted in this session.");
					return name === null ? xdevListing(xdev) : xdevDocs(xdev, name);
				},

View on GitHub (pinned to 9690622007)

Solutions

  1. Remove the line selector and rely on the query extraction.
  2. Remove the ?q= extraction and use only the line selector on the full resource.
  3. Use :raw with extraction if raw bytes of the extracted result are acceptable per the allowed kinds.

Example fix

// before
read("agent://api/list?q=users:5-10")
// after
read("agent://api/list?q=users")
Defensive patterns

Strategy: validation

Validate before calling

if (url.includes('?q=') && /:\d+(-\d+|\+\d+|-)?(,|$)/.test(url)) throw new Error('Drop either query extraction or the line selector');

Type guard

function hasConflictingFeatures(url) { const [u, sel] = splitInternalUrlSel(url); return /[?&]q=/.test(u) && sel !== undefined && !['raw','none'].includes(sel); }

Try / catch

try { return await read(url) } catch (e) { if (String(e.message).includes('query extraction')) { return await read(url.replace(/:\d.*$/, '')); } throw e; }

Prevention

When it happens

Trigger: read('agent://resource?q=foo:10-20') or any URL where hasExtraction is true and parsedSel.kind is a line range (not 'none' or 'raw').

Common situations: Appending a standard line-range selector out of habit onto a query-extraction URL; combining two narrowing features the agent generated independently.

Related errors


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