{"record":{"id":"7567318680f9f41c","repo":"can1357/oh-my-pi","slug":"invalid-conflict-uri-raw-must-be-conflict","errorCode":null,"errorMessage":"Invalid conflict URI '${raw}': must be 'conflict://<N>', 'conflict://<N>/<scope>', or 'conflict://*' where N is a positive integer surfaced by a prior `read`.","messagePattern":"Invalid conflict URI '(.+?)': must be 'conflict://<N>', 'conflict://<N>/<scope>', or 'conflict://\\*' where N is a positive integer surfaced by a prior `read`\\.","errorType":"validation","errorClass":"ToolError","httpStatus":null,"severity":"error","filePath":"packages/coding-agent/src/tools/conflict-detect.ts","lineNumber":300,"sourceCode":"\tconst match = raw.match(CONFLICT_URI_RE);\n\tif (!match) return null;\n\tconst recoveredPrefix = match[1];\n\tconst tail = match[2];\n\tconst slashIdx = tail.indexOf(\"/\");\n\tconst idPart = slashIdx === -1 ? tail : tail.slice(0, slashIdx);\n\tconst scopePart = slashIdx === -1 ? undefined : tail.slice(slashIdx + 1);\n\n\tif (idPart === \"*\") {\n\t\tif (scopePart !== undefined) {\n\t\t\tthrow new ToolError(\n\t\t\t\t`Invalid conflict URI '${raw}': wildcard 'conflict://*' does not accept a scope segment. Drop '/${scopePart}' or use a numeric id.`,\n\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","sourceCodeStart":282,"sourceCodeEnd":318,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/coding-agent/src/tools/conflict-detect.ts#L282-L318","documentation":"parseConflictUri throws this when the conflict id segment is not a positive integer (and not the '*' wildcard). Valid forms are conflict://<N>, conflict://<N>/<scope>, or conflict://*; anything else with the conflict:// scheme — 'conflict://abc', 'conflict://latest', 'conflict://3.2' — is rejected early with this message rather than failing later with a confusing not-found.","triggerScenarios":"Passing a non-numeric id like 'conflict://latest' or 'conflict://head'; including units or formatting ('conflict://3rd', 'conflict://#3'); an id placeholder left unsubstituted in a template.","commonSituations":"Agents hallucinating descriptive ids ('latest', 'first'); scripts interpolating undefined variables into the URI; ids copied from docs without replacing N.","solutions":["Use the numeric id surfaced by a prior read of the file (conflict ids are assigned when conflicts are registered).","Read the conflicted file first to register conflicts and obtain valid numeric ids, then reference them.","Fix id interpolation in scripts/templates so a real number or '*' lands in the URI."],"exampleFix":"// before\nwrite({ path: 'conflict://latest', content });\n// after\nconst id = conflicts[0].id; // from a prior read\nwrite({ path: `conflict://${id}`, content });","handlingStrategy":"validation","validationCode":"if (!/^(?:[^:]+:)?conflict:\\/\\/(\\d+|\\*)(?:\\/(?:ours|theirs|base))?$/.test(path)) {\n  throw new Error(`not a valid conflict URI: ${path}`);\n}","typeGuard":"function isConflictUri(s) {\n  return /^(?:[^:]+:)?conflict:\\/\\/(\\d+|\\*)(?:\\/(?:ours|theirs|base))?$/.test(s);\n}","tryCatchPattern":"try {\n  parseConflictUri(raw);\n} catch (err) {\n  if (String(err?.message).includes(\"must be 'conflict://<N>'\")) {\n    // recover: re-read the file to get numeric ids\n  } else throw err;\n}","preventionTips":["Only use ids returned by a prior read's conflict registration.","Never interpolate descriptive strings ('latest', 'first') into conflict URIs.","Keep a registry mapping labels → numeric conflict ids.","Validate URI shape before calling read/write."],"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"}