can1357/oh-my-pi · error · ToolError

Conflict #${id} not found. Conflict ids are registered when

Error message

Conflict #${id} not found. Conflict ids are registered when \`read\` surfaces a marker block; re-read the file to get a current id.

What it means

Conflict-marker regions get numeric ids registered in session conflict history only when a prior read surfaced the marker block. Reading a conflict region with an id that is absent (stale session, wrong id, or never-registered) throws this error and instructs re-reading the file.

Source

Thrown at packages/coding-agent/src/tools/read.ts:1912

		if (truncationInfo) {
			resultBuilder.truncation(truncationInfo.result, truncationInfo.options);
		}
		if (columnTruncated > 0) {
			resultBuilder.limits({ columnMax: columnTruncated });
		}
		return resultBuilder.done();
	}

	/**
	 * Render a `conflict://<N>` (or `conflict://<N>/<scope>`) region as
	 * regular file content. The lines are emitted with their original
	 * file line numbers so hashline anchors line up with the source
	 * file, and no truncation footer is appended.
	 */
	async #readConflictRegion(id: number, scope: ConflictScope | undefined): Promise<AgentToolResult<ReadToolDetails>> {
		const entry: ConflictEntry | undefined = getConflictHistory(this.session).get(id);
		if (!entry) {
			throw new ToolError(
				`Conflict #${id} not found. Conflict ids are registered when \`read\` surfaces a marker block; re-read the file to get a current id.`,
			);
		}

		const region = renderConflictRegion(entry, scope);
		const displayMode = resolveFileDisplayMode(this.session);
		const shouldAddHashLines = displayMode.hashLines;
		const shouldAddLineNumbers = shouldAddHashLines ? false : displayMode.lineNumbers;

		const rawText = region.lines.join("\n");
		const tag = shouldAddHashLines ? await recordFileSnapshot(this.session, entry.absolutePath) : undefined;
		const hashContext = tag
			? hashlineHeaderContext(formatPathRelativeToCwd(entry.absolutePath, this.session.cwd), tag)
			: undefined;
		const formattedBody = formatTextWithMode(rawText, region.startLine, shouldAddHashLines, shouldAddLineNumbers);
		const formattedText = prependHashlineHeader(formattedBody, hashContext);

		const details: ReadToolDetails = {

View on GitHub (pinned to 9690622007)

Solutions

  1. Re-read the file containing conflict markers so current ids are registered, then use the returned id.
  2. Check you are in the same session where the conflict was originally surfaced.
  3. If the conflict was already resolved, read the file normally instead of via the conflict-region API.

Example fix

// before
readConflict(id=7)  // from previous session
// after
const res = await read("file.txt"); // surfaces marker block, registers id
readConflict(id=res.conflictId)
Defensive patterns

Strategy: try-catch

Validate before calling

const ids = getConflictHistory(session); if (!ids.has(id)) { await read(conflictFile); /* refresh ids */ }

Type guard

function conflictExists(session, id) { return getConflictHistory(session).has(id); }

Try / catch

try { return await readConflict(id) } catch (e) { if (String(e.message).includes('not found') && e.message.includes('Conflict')) { await read(file); /* get fresh id from result, retry once */ } else throw e; }

Prevention

When it happens

Trigger: Calling the conflict-region read path (read with a conflict id qualifier) with an id not present in getConflictHistory(session): id from a previous session, id already cleared after resolution, or an invented id.

Common situations: Session restarted after resolving some conflicts; agent cached conflict ids from an earlier read; merge-conflict markers re-generated so history was reset.

Related errors


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