can1357/oh-my-pi · error

${referenceSeparator} after MATCH reads as the ${REWRITE_HEA

Error message

${referenceSeparator} after MATCH reads as the ${REWRITE_HEADER} separator, leaving REWRITE empty.\nCopy-ready corrected payload (fill in the final text):\n${correctedLines.join("\n")}

What it means

When a MATCH operation is followed by a line equal to the » separator, the separator would terminate the pattern and leave an empty REWRITE. The parser detects this recoverable mistake and throws an error that embeds a copy-ready corrected payload: the erroneous separator line is replaced with » and a '<final text>' placeholder is inserted, so the caller can fill in the replacement and re-send.

Source

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

	let patternLines: string[] = [];
	let rewriteLines: string[] = [];
	let referenceSeparator: string | undefined;

	const finish = (endIndex: number) => {
		const sourcePatternText = normalizeBlock(patternLines, false);
		const rewriteText = normalizeBlock(rewriteLines, true);
		if (referenceSeparator !== undefined && rewriteText.trim() === "") {
			// A trailing »N produced no rewrite: noise after an inline operation;
			// after a legacy MATCH the final text is missing — hand back a
			// fill-in skeleton instead of echoing the broken payload.
			if (!hasInlineSelection(sourcePatternText)) {
				const correctedLines = [...lines];
				const separatorIndex = correctedLines.findLastIndex(
					(line, index) => index < endIndex && line.trim() === referenceSeparator,
				);
				correctedLines[separatorIndex] = REWRITE_HEADER;
				correctedLines.splice(endIndex, 0, "<final text>");
				throw new Error(
					`${referenceSeparator} after MATCH reads as the ${REWRITE_HEADER} separator, leaving REWRITE empty.\nCopy-ready corrected payload (fill in the final text):\n${correctedLines.join("\n")}`,
				);
			}
			operations.push(createOperation(sourcePatternText, "", allMatches, operations.length + 1, false));
			return;
		}
		operations.push(createOperation(sourcePatternText, rewriteText, allMatches, operations.length + 1, true));
	};
	const pendingSeparatorErrors = new Map<number, string>();
	const finishPattern = (endIndex: number) => {
		const sourcePatternText = normalizeBlock(patternLines, false);
		if (
			hasInlineSelection(sourcePatternText) ||
			hasMarkerLines(sourcePatternText) ||
			hasBareDesired(sourcePatternText)
		) {
			operations.push(createOperation(sourcePatternText, "", allMatches, operations.length + 1, false));
			return;

View on GitHub (pinned to 9690622007)

Solutions

  1. Use the corrected payload printed in the error: keep the » header line and fill in '<final text>' after it
  2. If no rewrite is intended, delete the bare » line so the MATCH stays pattern-only (or use allMatches form)
  3. Re-send the full payload — operations apply atomically

Example fix

// before
§ MATCH
old text
»
// after
§ MATCH
old text
»
<final text>
Defensive patterns

Strategy: validation

Validate before calling

const lines = payload.split('\n');
for (let i = 0; i < lines.length; i++) {
  if (lines[i].trim() === '»' && lines[i + 1] === undefined) {
    throw new Error('bare » line terminates MATCH with an empty REWRITE');
  }
}

Try / catch

try {
  applySloppy(content, input, ctx);
} catch (err) {
  if (err instanceof Error && err.message.includes('reads as the » separator')) {
    const corrected = err.message.match(/Copy-ready corrected payload[\s\S]*/)?.[0];
    // fill '<final text>' in corrected payload and re-send
  } else throw err;
}

Prevention

When it happens

Trigger: A payload where a MATCH section's pattern is terminated by a line consisting solely of » (the reference separator) instead of the » rewrite header, producing an empty rewrite body.

Common situations: An LLM uses a bare '»' line as a section divider without knowing it doubles as the REWRITE header; copy/paste collapses '» rewrite' into just '»'.

Related errors


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