can1357/oh-my-pi · error

Operation has an empty pattern.

Error message

Operation ${operationNumber} has an empty pattern.

What it means

parsePattern validates each operation's MATCH text. An operation whose pattern is blank (only whitespace) after the « opener carries no information about what to replace, so it is rejected with the operation number. A sibling error ("has no visible current text") covers patterns whose characters are all stripped by normalization. validateSelectionMarkers then checks ⟪...⟫ selection markers.

Solutions

  1. Put the exact current text to be replaced between « and » — the pattern must have non-whitespace content.
  2. For an insertion, include the anchor line before the insertion point as the pattern and emit anchor+new text in the rewrite.
  3. Check the payload wasn't truncated or stripped of its pattern lines between generation and apply.

Example fix

// before
«
»
new text

// after
«
anchor line
»
anchor line
new text
Defensive patterns

Strategy: validation

Validate before calling

// per-operation: pattern must contain visible text
const ops = body.split(/^«\*?$/m).slice(1);
for (let i = 0; i < ops.length; i++) {
  const pattern = ops[i].split(/^»/m)[0];
  if (pattern.trim() === "") throw new Error(`operation ${i + 1} has an empty pattern`);
}

Type guard

const hasVisiblePattern = (op: string): boolean => op.split(/^»/m)[0].trim() !== "";

Try / catch

catch (err) {
  if (err instanceof Error && err.message.includes("has an empty pattern")) {
    // regenerate the operation with an anchored match block
  }
}

Prevention

When it happens

Trigger: A payload with « followed immediately by » (empty match), or a match block containing only spaces/tabs/newlines; also occurs when a model emits the opener and separator back-to-back intending an insertion-only edit.

Common situations: Models attempting pure insertions with an empty MATCH block; truncated payloads where pattern lines were lost; whitespace-only bodies after copy-paste; using this format for file creation instead of the proper add mechanism.

Related errors


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

Appendix: source

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

				starts.push(index);
				ends.push(next);
			}
		}
		index = next;
	}
	return { text, starts, ends };
}

function patternGapAt(source: string, offset: number): string | undefined {
	return source.startsWith(GAP, offset) ? GAP : undefined;
}

function patternContainsGap(source: string): boolean {
	return source.includes(GAP);
}

function parsePattern(pattern: string, operationNumber: number): ParsedPattern {
	if (pattern.trim() === "") throw new Error(`Operation ${operationNumber} has an empty pattern.`);
	validateSelectionMarkers(pattern, operationNumber);
	const hasGap = patternContainsGap(pattern);
	const hasSelection = pattern.includes(SELECT_OPEN);
	if (!hasGap && !hasSelection) {
		const normalized = normalizeText(pattern).text;
		if (normalized === "") throw new Error(`Operation ${operationNumber} has no visible current text.`);
		return {
			tokens: [{ kind: "literal", text: pattern, normalized }],
			selectionStart: 0,
			selectionEnd: 1,
			insertion: false,
			lineInsertion: false,
			selectedCaptureIndices: [],
			selectionRanges: [],
			selectionPairs: [],
			literalFallback: undefined,
		};
	}

View on GitHub (pinned to 9690622007)