can1357/oh-my-pi · error
Operation ${operationNumber} has an unmatched closing select
Error message
Operation ${operationNumber} has an unmatched closing selection marker ⟫; add opening ⟪. What it means
While expanding selections, the scanner walks the pattern character by character; if it encounters a closing ⟫ before any opening ⟪, the closing marker has no counterpart. This is the character-level equivalent of the count-based check and catches closings that appear before their opener in stream order.
Source
Thrown at packages/coding-agent/src/edit/sloppy.ts:648
}
function parseInlinePattern(
pattern: string,
operationNumber: number,
): { patternText: string; replacements: string[]; notes: string[] } {
validateSelectionMarkers(pattern, operationNumber);
let patternText = "";
const replacements: string[] = [];
const notes: string[] = [];
let sawBare = false;
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);View on GitHub (pinned to 9690622007)
Solutions
- Move the ⟫ to after the text it should close (after the matching ⟪… span)
- Add the missing ⟪ before the text you intend to select
- Remove the stray ⟫ if no selection was intended
Example fix
// before «old ⟫text⟪»new // after «old ⟪text⟫»new
Defensive patterns
Strategy: validation
Validate before calling
let depth = 0;
for (const ch of pattern) {
if (ch === '⟪') depth++;
if (ch === '⟫') { if (depth === 0) throw new Error('⟫ before ⟪'); depth--; }
}
if (depth !== 0) throw new Error('unclosed ⟪'); Try / catch
try {
applySloppy(content, input, ctx);
} catch (err) {
if (err instanceof Error && err.message.includes('unmatched closing selection marker')) {
// reorder/remove the stray ⟫ and re-send
} else throw err;
} Prevention
- Ensure each ⟫ appears strictly after its ⟪ in stream order
- Escape or avoid quoting code that contains ⟫ literally inside selections
- Validate marker ordering with a depth counter before submitting
When it happens
Trigger: applySloppy operation pattern where an ⟫ occurs at a position with no preceding active ⟪ (e.g. pattern starts with ⟫, or a previous selection already consumed its opener).
Common situations: Reordered or duplicated marker characters when an LLM edits a payload; quoting code that itself contains ⟫; manual payload hand-editing that moved the close before the open.
Related errors
- Operation ${operationNumber} has an unclosed selection marke
- Operation ${operationNumber} has nested selection markers; u
- Operation ${operationNumber} mixes inline and bare selection
- ${REWRITE_HEADER}${reference[1]} is valid only inside an inl
- ${REWRITE_HEADER}${reference[1]} is valid only in REWRITE, n
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/44bd672d75622e52.
Report an issue: GitHub.