can1357/oh-my-pi · error · ToolError
Invalid URL line selector: ${sel}
Error message
Invalid URL line selector: ${sel} What it means
Belt-and-suspenders branch in parseReadUrlTarget: after isUrlSelectorToken has already vetted selector tokens, parseLineRanges is expected to always succeed. If it returns null, the token was vetted as a selector but is not a parseable line range, so this error fires. Hitting it in practice means a selector token slipped past the vetting or the range grammar changed.
Source
Thrown at packages/coding-agent/src/tools/fetch.ts:196
}
let raw = false;
let ranges: readonly LineRange[] | undefined;
for (const sel of embedded?.sels ?? []) {
if (sel.toLowerCase() === "raw") {
raw = true;
continue;
}
if (ranges !== undefined) {
// Two range groups on the same URL (`…:5-10:20-30`) — combine with commas instead.
throw new ToolError(
`URL selector has multiple range groups; combine them with commas (e.g. \`:5-10,20-30\`).`,
);
}
const parsed = parseLineRanges(sel);
if (parsed === null) {
// Shouldn't happen — isUrlSelectorToken vetted it. Belt-and-suspenders.
throw new ToolError(`Invalid URL line selector: ${sel}`);
}
ranges = parsed;
}
if (!ranges || ranges.length === 0) return { path: urlPath, raw };
if (ranges.length === 1) {
const r = ranges[0];
return {
path: urlPath,
raw,
offset: r.startLine,
limit: r.endLine !== undefined ? r.endLine - r.startLine + 1 : undefined,
};
}
return { path: urlPath, raw, ranges };
}
/**View on GitHub (pinned to 9690622007)
Solutions
- Use a plain, well-formed range selector such as `:5` or `:5-10` (comma-join multiple ranges).
- Drop the selector entirely to read the whole URL.
- If you believe the selector is valid, it is a vet/parser mismatch bug — report it with the exact URL used.
Example fix
// before "https://example.com/file.txt:abc" // after "https://example.com/file.txt:1-10"
Defensive patterns
Strategy: validation
Validate before calling
function validSelector(sel: string): boolean { return /^raw$|^[0-9]+(-[0-9]+)?(,[0-9]+(-[0-9]+)?)*$/.test(sel); }
if (!validSelector(sel)) throw new Error(`bad selector: ${sel}`); Type guard
function isLineRangeSelector(sel: string): boolean { return /^[0-9]+(-[0-9]+)?(,[0-9]+(-[0-9]+)?)*$/.test(sel); } Try / catch
try {
await fetchTool.readUrl(id, { url }, signal);
} catch (e) {
if (e instanceof ToolError && e.message.startsWith("Invalid URL line selector")) {
// drop the selector or fix it, then retry
} else throw e;
} Prevention
- Build selectors only from the documented grammar: line numbers, N-M ranges, comma-joined groups, optional `raw` token.
- Never pass free-text after the URL's colon.
- After upgrading versions, re-validate any URL templates that embed selectors.
When it happens
Trigger: Passing a URL selector token that passes isUrlSelectorToken but fails parseLineRanges — e.g. a malformed or hypothetical future selector form like `:abc` if vetting rules drift out of sync with the range parser.
Common situations: Rare in practice due to pre-vetting; most likely after a version upgrade where the selector grammar changed, or from hand-crafted URLs with exotic selector tokens.
Related errors
- URL selector has multiple range groups; combine them with co
- Discord webhook credential is not a valid URL
- Discord webhook credential does not contain a webhook ID and
- Discord attachment URL is invalid
- ${destination} returned an invalid image URL
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/d14926f185550b56.
Report an issue: GitHub.