can1357/oh-my-pi · error

Operation ${operationNumber} has nested selection markers; u

Error message

Operation ${operationNumber} has nested selection markers; use one selection per replacement.

What it means

A selection span (⟪…⟫) may not contain another ⟪. Nested selections are ambiguous — which span does the replacement target? The parser rejects them outright and asks for one selection per replacement.

Source

Thrown at packages/coding-agent/src/edit/sloppy.ts:659

	let sawInline = false;

	for (let index = 0; index < pattern.length; ) {
		const codePoint = pattern.codePointAt(index);
		if (codePoint === undefined) break;
		const character = String.fromCodePoint(codePoint);
		if (character === SELECT_CLOSE) {
			throw new Error(`Operation ${operationNumber} has an unmatched closing selection marker ⟫; add opening ⟪.`);
		}
		if (character !== SELECT_OPEN) {
			patternText += character;
			index += character.length;
			continue;
		}

		const close = pattern.indexOf(SELECT_CLOSE, index + character.length);
		const selected = pattern.slice(index + character.length, close);
		if (selected.includes(SELECT_OPEN)) {
			throw new Error(
				`Operation ${operationNumber} has nested selection markers; use one selection per replacement.`,
			);
		}
		const divider = selected.indexOf(SELECT_DIVIDER);
		if (divider === -1) {
			sawBare = true;
			patternText += pattern.slice(index, close + SELECT_CLOSE.length);
		} else {
			sawInline = true;
			if (selected.indexOf(SELECT_DIVIDER, divider + SELECT_DIVIDER.length) === -1) {
				patternText += `${SELECT_OPEN}${selected.slice(0, divider)}${SELECT_CLOSE}`;
				replacements.push(selected.slice(divider + SELECT_DIVIDER.length));
			} else {
				const resolved = resolveLiteralDividers(selected, operationNumber);
				patternText += `${SELECT_OPEN}${resolved.old}${SELECT_CLOSE}`;
				replacements.push(resolved.desired);
				notes.push(resolved.note);
			}

View on GitHub (pinned to 9690622007)

Solutions

  1. Split into two operations, one selection each
  2. Remove the inner ⟪/⟫ if only the outer span should be replaced
  3. If the inner markers are literal characters in the code, escape them or restructure the pattern so they fall outside a selection

Example fix

// before
⟪a ⟪b│x⟫ c⟫»y
// after
⟪a b c⟫»y  (or two separate ops for a and b)
Defensive patterns

Strategy: validation

Validate before calling

let open = false;
for (const ch of pattern) {
  if (ch === '⟪') { if (open) throw new Error('nested selection'); open = true; }
  if (ch === '⟫') open = false;
}

Try / catch

try {
  applySloppy(content, input, ctx);
} catch (err) {
  if (err instanceof Error && err.message.includes('nested selection markers')) {
    // split into one selection per operation and re-send
  } else throw err;
}

Prevention

When it happens

Trigger: An operation pattern like ⟪outer ⟪inner│new⟫ text⟫ where a second ⟪ appears inside the currently open selection before its ⟫.

Common situations: An LLM tries to replace two overlapping/nearby spans with one selection; markers accidentally doubled around the same text; the intended inner ⟪ is actually literal content (escape or rewrite it as plain text).

Related errors


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