can1357/oh-my-pi · error · ToolError

`conflict://*` has nothing to resolve — no conflicts are cur

Error message

`conflict://*` has nothing to resolve — no conflicts are currently registered. Re-read the file(s) with conflicts first.

What it means

The conflict://* bulk-resolve mode requires at least one registered conflict entry in the session's conflict history. If `read` never surfaced any conflict markers (so nothing was registered), the wildcard resolve is a no-op and the tool throws this ToolError instead.

Source

Thrown at packages/coding-agent/src/tools/write.ts:949

	 * ours side rather than collapsing every conflict to the first
	 * block's ours.
	 *
	 * All-or-nothing semantics within a file: if any splice for a file
	 * fails (stale anchors, missing base for `@base`, etc.), that file is
	 * left untouched and the error is surfaced. Files that succeed are
	 * still written. The result text reports per-file counts so the agent
	 * can re-read the failed files and retry.
	 */
	async #resolveAllConflicts(
		replacementContent: string,
		stripped: boolean,
		signal: AbortSignal | undefined,
		rawContent: string = replacementContent,
	): Promise<AgentToolResult<WriteToolDetails>> {
		const history = getConflictHistory(this.session);
		const allEntries = history.entries();
		if (allEntries.length === 0) {
			throw new ToolError(
				"`conflict://*` has nothing to resolve — no conflicts are currently registered. Re-read the file(s) with conflicts first.",
			);
		}

		// Per-id directive mode: content made solely of `<id>: @side` lines
		// resolves each listed conflict with that side in one call. Ideal for
		// merge-hell files where dozens of pick-one blocks each need their own
		// winner — one call instead of one write per conflict. Parsed from the
		// PRE-strip content: hashline prefix stripping would otherwise eat the
		// `<id>: ` heads as echoed line numbers.
		const directives = resolveBulkDirectives(rawContent, replacementContent);
		if (directives) {
			const known = new Set(allEntries.map(entry => entry.id));
			const unknown = [...directives.keys()].filter(id => !known.has(id));
			if (unknown.length > 0) {
				throw new ToolError(
					`Bulk directive references unknown conflict id(s) ${unknown.map(id => `#${id}`).join(", ")}. Currently registered: ${allEntries.map(e => `#${e.id}`).join(", ")}.`,
				);

View on GitHub (pinned to 9690622007)

Solutions

  1. Re-read the conflicted file(s) with `read` so the marker blocks register conflict entries.
  2. If all conflicts were already resolved, skip the conflict://* call entirely.
  3. Verify the file actually contains conflict markers (<<<<<<< / ======= / >>>>>>>) before reading for conflicts.
Defensive patterns

Strategy: validation

Validate before calling

const hasMarkers = (await Bun.file(p).text()).includes("<<<<<<<");
if (!hasMarkers) throw new Error("No conflict markers in file; conflict://* will fail");

Try / catch

try {
  await write("conflict://*", directives);
} catch (err) {
  if (String(err.message).includes("nothing to resolve")) {
    // no conflicts registered — re-read or skip
  }
  throw err;
}

Prevention

When it happens

Trigger: Calling write with path conflict://* when the conflict history is empty — no file was read with conflict markers, or all previously registered conflicts were already resolved.

Common situations: Agent assumes conflicts exist without reading the files first; a retry loop after all conflicts were resolved in the previous attempt; running the bulk resolve in a fresh session where prior conflicts were never registered.

Related errors


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