can1357/oh-my-pi · error · ToolError

Multi-range line selectors are not supported for directory l

Error message

Multi-range line selectors are not supported for directory listings.

What it means

Directory listings accept a single offset/limit window derived from the selector, so a comma-separated multi-range selector (isMultiRange) cannot be applied. ReadTool rejects the combination up front.

Source

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

							// The referenced plan disappeared after resolution; continue through
							// the ordinary delimited-path fallback and not-found error.
						}
					}
				}

				if (!recoveredApprovedPlan && !suffixResolution) {
					const delimitedResult = await this.#tryReadDelimitedPaths(readPath, signal);
					if (delimitedResult) return delimitedResult;
					throw new ToolError(`Path '${localReadPath}' not found`);
				}
			} else {
				throw error;
			}
		}

		if (isDirectory) {
			if (isMultiRange(parsed)) {
				throw new ToolError("Multi-range line selectors are not supported for directory listings.");
			}
			const { offset, limit } = selToOffsetLimit(parsed);
			// Directory listings are deterministic and fast; never abort them mid-scan
			// (an interrupt would otherwise surface a misleading "Operation aborted").
			const dirResult = await this.#readDirectory(absolutePath, offset, limit, undefined);
			if (suffixResolution) {
				dirResult.details ??= {};
				dirResult.details.suffixResolution = suffixResolution;
			}
			return dirResult;
		}

		if (parsed.kind === "conflicts") {
			return this.#readFileConflicts(absolutePath, suffixResolution, signal);
		}

		if (pdfImageRead) {
			return this.#readPdfPageScreenshot({

View on GitHub (pinned to 9690622007)

Solutions

  1. Use a single range or open-ended selector on the directory (e.g. ':1-20' or ':10-').
  2. Issue multiple directory reads, one per range, and merge results yourself.
  3. Drop the selector to get the full listing and slice locally.

Example fix

// before
read("src/:1-10,50-60")
// after
read("src/:1-10")  // repeat with :50-60 if needed
Defensive patterns

Strategy: validation

Validate before calling

const ranges = sel.split(','); if (isDir && ranges.length > 1) throw new Error('Use a single range for directory reads');

Type guard

function isMultiRangeSel(sel) { return typeof sel === 'string' && sel.includes(','); }

Try / catch

try { return await read(dir + ':' + sel) } catch (e) { if (String(e.message).includes('Multi-range')) { return await read(dir + ':' + sel.split(',')[0]); } throw e; }

Prevention

When it happens

Trigger: Reading a directory path with a multi-range selector such as 'src/:1-10,20-30' — the directory branch throws before #readDirectory runs.

Common situations: Reusing a multi-range selector that worked on a file against a directory; agent constructs a combined listing window across disjoint ranges of a tree listing.

Related errors


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