{"record":{"id":"8ed4972625b37b7a","repo":"can1357/oh-my-pi","slug":"reading-conflict-is-not-supported-wildcard","errorCode":null,"errorMessage":"Reading `conflict://*` is not supported — wildcards are write-only. Use the `<path>:conflicts` read selector for the full list of conflicts in a file, or read `conflict://<N>` to inspect a singl","messagePattern":"Reading `conflict://\\*` is not supported — wildcards are write-only\\. Use the `<path>:conflicts` read selector for the full list of conflicts in a file, or read `conflict://<N>` to inspect a singl","errorType":"exception","errorClass":"ToolError","httpStatus":null,"severity":"error","filePath":"packages/coding-agent/src/tools/read.ts","lineNumber":1107,"sourceCode":"\t\t\treadPath = expandPath(readPath);\n\t\t}\n\n\t\tif (IMAGE_ATTACHMENT_URI_REGEX.test(readPath)) {\n\t\t\tconst attachments = this.session.getImageAttachments?.() ?? [];\n\t\t\tconst attachment = attachments.find(entry => entry.uri === readPath);\n\t\t\tif (!attachment) {\n\t\t\t\tconst availableUris = attachments.map(entry => entry.uri).join(\", \") || \"none\";\n\t\t\t\tthrow new ToolError(\n\t\t\t\t\t`Could not resolve image attachment '${readPath}'. Available attachment URIs: ${availableUris}. Use one of the listed attachment URIs, or attach an image first when none are available.`,\n\t\t\t\t);\n\t\t\t}\n\t\t\treadPath = attachment.sourcePath;\n\t\t}\n\n\t\tconst conflictUri = parseConflictUri(readPath);\n\t\tif (conflictUri) {\n\t\t\tif (conflictUri.id === \"*\") {\n\t\t\t\tthrow new ToolError(\n\t\t\t\t\t\"Reading `conflict://*` is not supported — wildcards are write-only. Use the `<path>:conflicts` read selector for the full list of conflicts in a file, or read `conflict://<N>` to inspect a single block.\",\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn this.#readConflictRegion(conflictUri.id, conflictUri.scope);\n\t\t}\n\t\tconst displayMode = resolveFileDisplayMode(this.session);\n\n\t\tconst parsedUrlTarget = parseReadUrlTarget(readPath);\n\t\tif (parsedUrlTarget) {\n\t\t\tif (!this.session.settings.get(\"fetch.enabled\")) {\n\t\t\t\tthrow new ToolError(\"URL reads are disabled by settings.\");\n\t\t\t}\n\t\t\tconst urlRaw = parsedUrlTarget.raw;\n\t\t\tconst urlRanges = parsedUrlTarget.ranges;\n\t\t\tif (urlRanges !== undefined && urlRanges.length > 1) {\n\t\t\t\tconst entry = await fetchReadUrl(this.session, { path: parsedUrlTarget.path, raw: urlRaw }, signal, {\n\t\t\t\t\tensureArtifact: true,\n\t\t\t\t});","sourceCodeStart":1089,"sourceCodeEnd":1125,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/coding-agent/src/tools/read.ts#L1089-L1125","documentation":"conflict:// URIs address file-conflict blocks. The '*' id is write-only — it exists for resolving/writing all conflicts — and reading it is rejected with a ToolError directing you to the '<path>:conflicts' read selector for the full list or 'conflict://<N>' for a single block. This keeps bulk reads from dumping every conflict block at once.","triggerScenarios":"read('conflict://*') or read('conflict://path:*') used as a read target; model guessing the wildcard form after seeing conflict-resolution writes.","commonSituations":"Trying to enumerate conflicts in one shot; confusion between the write-side wildcard semantics and read-side selectors; exploration after a merge/edit conflict was flagged.","solutions":["Use '<path>:conflicts' to list all conflicts in a file.","Read one block at a time with 'conflict://<N>' using ids from that list.","Resolve conflicts via the write path (wildcard) if the goal is resolution, not inspection."],"exampleFix":"// before\nread('conflict://*')\n// after\nread('src/app.ts:conflicts')   // list all conflict blocks\nread('conflict://2')           // inspect block 2","handlingStrategy":"validation","validationCode":"const m = readPath.match(/^conflict:\\/\\/(.+)$/);\nif (m && m[1] === '*') {\n  // wildcard is write-only: use the file's :conflicts selector to enumerate\n  throw new Error(`Use '<path>:conflicts' to list conflicts, not ${readPath}`);\n}","typeGuard":null,"tryCatchPattern":"try {\n  return await readTool.execute({ path: target });\n} catch (e) {\n  if (e instanceof ToolError && target === 'conflict://*') {\n    const [file] = conflictFiles; // file you intended to inspect\n    return readTool.execute({ path: `${file}:conflicts` }); // list, then conflict://<N>\n  }\n  throw e;\n}","preventionTips":["Remember the split: conflict://* is write-only; reads use <path>:conflicts or conflict://<N>.","Enumerate conflicts with the :conflicts selector before reading individual blocks.","Only use the wildcard when writing conflict resolutions."],"tags":["conflict","uri","selector"],"backgroundTag":"unsupported-uri-wildcard","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}