{"record":{"id":"8142fb2ec3b77a15","repo":"can1357/oh-my-pi","slug":"invalid-conflict-uri-raw-scope-must-be-one-o","errorCode":null,"errorMessage":"Invalid conflict URI '${raw}': scope must be one of 'ours', 'theirs', 'base', or omitted (e.g. 'conflict://${id}/theirs').","messagePattern":"Invalid conflict URI '(.+?)': scope must be one of 'ours', 'theirs', 'base', or omitted \\(e\\.g\\. 'conflict://(.+?)/theirs'\\)\\.","errorType":"validation","errorClass":"ToolError","httpStatus":null,"severity":"error","filePath":"packages/coding-agent/src/tools/conflict-detect.ts","lineNumber":312,"sourceCode":"\t\t\t);\n\t\t}\n\t\treturn recoveredPrefix !== undefined ? { id: \"*\", recoveredPrefix } : { id: \"*\" };\n\t}\n\n\tif (!/^\\d+$/.test(idPart)) {\n\t\tthrow new ToolError(\n\t\t\t`Invalid conflict URI '${raw}': must be 'conflict://<N>', 'conflict://<N>/<scope>', or 'conflict://*' where N is a positive integer surfaced by a prior \\`read\\`.`,\n\t\t);\n\t}\n\tconst id = Number.parseInt(idPart, 10);\n\tif (!Number.isFinite(id) || id < 1) {\n\t\tthrow new ToolError(`Invalid conflict URI '${raw}': id must be ≥ 1.`);\n\t}\n\n\tlet scope: ConflictScope | undefined;\n\tif (scopePart !== undefined) {\n\t\tif (!CONFLICT_SCOPES.has(scopePart as ConflictScope)) {\n\t\t\tthrow new ToolError(\n\t\t\t\t`Invalid conflict URI '${raw}': scope must be one of 'ours', 'theirs', 'base', or omitted (e.g. 'conflict://${id}/theirs').`,\n\t\t\t);\n\t\t}\n\t\tscope = scopePart as ConflictScope;\n\t}\n\n\treturn recoveredPrefix !== undefined ? { id, scope, recoveredPrefix } : { id, scope };\n}\n\n/** Result of {@link spliceConflict}: the new file text plus any boundary-echo repair applied. */\nexport interface ConflictSplice {\n\ttext: string;\n\t/** Replacement lines dropped because they duplicated the context directly above the region. */\n\ttrimmedLeading: number;\n\t/** Replacement lines dropped because they duplicated the context directly below the region. */\n\ttrimmedTrailing: number;\n}\n","sourceCodeStart":294,"sourceCodeEnd":330,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/coding-agent/src/tools/conflict-detect.ts#L294-L330","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nwrite({ path: 'conflict://3/remote', content: '@remote' });\n// after\nwrite({ path: 'conflict://3/theirs', content: '@theirs' });","handlingStrategy":"validation","validationCode":"const SCOPES = new Set(['ours', 'theirs', 'base']);\nif (scope !== undefined && !SCOPES.has(scope)) {\n  throw new Error(`scope must be ours|theirs|base, got ${scope}`);\n}\nconst uri = scope ? `conflict://${id}/${scope}` : `conflict://${id}`;","typeGuard":"function isConflictScope(s) {\n  return s === 'ours' || s === 'theirs' || s === 'base';\n}","tryCatchPattern":"try {\n  parseConflictUri(raw);\n} catch (err) {\n  if (String(err?.message).includes(\"scope must be one of 'ours', 'theirs', 'base'\")) {\n    // map git terms: local→ours, remote/incoming→theirs, ancestor→base\n  } else throw err;\n}","preventionTips":["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."],"tags":["conflict-resolution","uri-parsing","validation"],"backgroundTag":"invalid-uri-format","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}