can1357/oh-my-pi · error · ToolError
Invalid conflict URI '${raw}': scope must be one of 'ours',
Error message
Invalid conflict URI '${raw}': scope must be one of 'ours', 'theirs', 'base', or omitted (e.g. 'conflict://${id}/theirs'). What it means
parseConflictUri throws this when the scope segment after the id is not one of the allowed conflict scopes: 'ours', 'theirs', or 'base' (or omitted entirely). Unknown scopes like 'local', 'remote', 'incoming', or 'merged' are rejected so a typo can't silently resolve to the wrong side of the conflict.
Source
Thrown at packages/coding-agent/src/tools/conflict-detect.ts:312
);
}
return recoveredPrefix !== undefined ? { id: "*", recoveredPrefix } : { id: "*" };
}
if (!/^\d+$/.test(idPart)) {
throw new ToolError(
`Invalid conflict URI '${raw}': must be 'conflict://<N>', 'conflict://<N>/<scope>', or 'conflict://*' where N is a positive integer surfaced by a prior \`read\`.`,
);
}
const id = Number.parseInt(idPart, 10);
if (!Number.isFinite(id) || id < 1) {
throw new ToolError(`Invalid conflict URI '${raw}': id must be ≥ 1.`);
}
let scope: ConflictScope | undefined;
if (scopePart !== undefined) {
if (!CONFLICT_SCOPES.has(scopePart as ConflictScope)) {
throw new ToolError(
`Invalid conflict URI '${raw}': scope must be one of 'ours', 'theirs', 'base', or omitted (e.g. 'conflict://${id}/theirs').`,
);
}
scope = scopePart as ConflictScope;
}
return recoveredPrefix !== undefined ? { id, scope, recoveredPrefix } : { id, scope };
}
/** Result of {@link spliceConflict}: the new file text plus any boundary-echo repair applied. */
export interface ConflictSplice {
text: string;
/** Replacement lines dropped because they duplicated the context directly above the region. */
trimmedLeading: number;
/** Replacement lines dropped because they duplicated the context directly below the region. */
trimmedTrailing: number;
}
View on GitHub (pinned to 9690622007)
Solutions
- Use exactly one of 'ours', 'theirs', or 'base' as the scope (lowercase).
- Map git terminology: local/current → ours, remote/incoming → theirs, ancestor/common → base.
- Omit the scope entirely (conflict://3) to operate on the whole conflict block with @-tokens in content.
Example fix
// before
write({ path: 'conflict://3/remote', content: '@remote' });
// after
write({ path: 'conflict://3/theirs', content: '@theirs' }); Defensive patterns
Strategy: validation
Validate before calling
const SCOPES = new Set(['ours', 'theirs', 'base']);
if (scope !== undefined && !SCOPES.has(scope)) {
throw new Error(`scope must be ours|theirs|base, got ${scope}`);
}
const uri = scope ? `conflict://${id}/${scope}` : `conflict://${id}`; Type guard
function isConflictScope(s) {
return s === 'ours' || s === 'theirs' || s === 'base';
} Try / catch
try {
parseConflictUri(raw);
} catch (err) {
if (String(err?.message).includes("scope must be one of 'ours', 'theirs', 'base'")) {
// map git terms: local→ours, remote/incoming→theirs, ancestor→base
} else throw err;
} Prevention
- Memorize the exact vocabulary: ours, theirs, base — lowercase.
- Translate git terms (local/remote/incoming) before building URIs.
- Centralize scope-string constants in one place.
- Omit the scope when unsure; use @-tokens in content instead.
When it happens
Trigger: Passing 'conflict://3/local' or 'conflict://3/remote' (git's other naming for ours/theirs); typos like 'conflict://3/Our' or 'conflict://3/there'; trailing slashes or extra path segments creating a bogus scope.
Common situations: Developers used to git terminology (local/remote, ours/theirs, current/incoming) using git words instead of the tool's scope vocabulary; case-sensitivity mistakes; agents paraphrasing scopes.
Related errors
- Invalid conflict URI '${raw}': wildcard 'conflict://*' does
- Invalid conflict URI '${raw}': must be 'conflict://<N>', 'co
- Invalid conflict URI '${raw}': id must be ≥ 1.
- Conflict #${entry.id} has no base section (2-way merge). `@b
- Unsupported language '{value}'. Supported: {}
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/8142fb2ec3b77a15.
Report an issue: GitHub.