{"record":{"id":"3b11659d711fa55c","repo":"can1357/oh-my-pi","slug":"conflict-entry-id-has-no-base-section-2-way-m-3b1165","errorCode":null,"errorMessage":"Conflict #${entry.id} has no base section (2-way merge). 'conflict://${entry.id}/base' is only valid for diff3 conflicts.","messagePattern":"Conflict #(.+?) has no base section \\(2-way merge\\)\\. 'conflict://(.+?)/base' is only valid for diff3 conflicts\\.","errorType":"exception","errorClass":"ToolError","httpStatus":null,"severity":"error","filePath":"packages/coding-agent/src/tools/conflict-detect.ts","lineNumber":616,"sourceCode":" *   original file positions.\n *\n * Bare (no scope) returns the full block including marker lines. A\n * scoped view returns only that side's body — `base` throws when the\n * recorded conflict is a 2-way merge with no base section.\n */\nexport function renderConflictRegion(\n\tentry: ConflictEntry,\n\tscope: ConflictScope | undefined,\n): { lines: string[]; startLine: number } {\n\tif (scope === \"ours\") {\n\t\treturn { lines: [...entry.oursLines], startLine: entry.startLine + 1 };\n\t}\n\tif (scope === \"theirs\") {\n\t\treturn { lines: [...entry.theirsLines], startLine: entry.separatorLine + 1 };\n\t}\n\tif (scope === \"base\") {\n\t\tif (entry.baseLines === undefined || entry.baseLine === undefined) {\n\t\t\tthrow new ToolError(\n\t\t\t\t`Conflict #${entry.id} has no base section (2-way merge). 'conflict://${entry.id}/base' is only valid for diff3 conflicts.`,\n\t\t\t);\n\t\t}\n\t\treturn { lines: [...entry.baseLines], startLine: entry.baseLine + 1 };\n\t}\n\tconst out: string[] = [];\n\tout.push(markerLine(\"<<<<<<<\", entry.oursLabel));\n\tout.push(...entry.oursLines);\n\tif (entry.baseLines !== undefined) {\n\t\tout.push(markerLine(\"|||||||\", entry.baseLabel));\n\t\tout.push(...entry.baseLines);\n\t}\n\tout.push(\"=======\");\n\tout.push(...entry.theirsLines);\n\tout.push(markerLine(\">>>>>>>\", entry.theirsLabel));\n\treturn { lines: out, startLine: entry.startLine };\n}\n","sourceCodeStart":598,"sourceCodeEnd":634,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/coding-agent/src/tools/conflict-detect.ts#L598-L634","documentation":"The scope reader throws when reading conflict://<id>/base for a conflict that has no base section. baseLines/baseLine are only populated for diff3-style conflicts (which record the common ancestor between the ======= and >>>>>>> markers); for plain 2-way conflicts that section doesn't exist, so requesting it throws instead of returning empty content.","triggerScenarios":"Reading 'conflict://5/base' where conflict 5 came from a 2-way merge; iterating all scopes (ours/theirs/base) for every registered conflict without checking which style produced them; an agent assuming diff3 output on a repo configured with merge.conflictStyle=diff.","commonSituations":"Repos without git config merge.conflictStyle=diff3/zdiff3; conflicts imported from tools (rebase, cherry-pick) that emit 2-way markers; generic tooling that blindly requests every scope.","solutions":["Read the conflict without a scope (conflict://5) or use /ours and /theirs, which exist for both styles.","Enable diff3 style (git config merge.conflictStyle diff3) and re-trigger the merge to get a base section, then re-read.","Check the conflict entry's baseLines (or conflict style) before requesting the base scope in scripts."],"exampleFix":"// before\nconst base = await read({ path: 'conflict://5/base' }); // 2-way conflict\n// after\nconst whole = await read({ path: 'conflict://5' }); // ours+theirs, safe for both styles","handlingStrategy":"type-guard","validationCode":"if (entry.baseLines !== undefined) {\n  const base = await read({ path: `conflict://${entry.id}/base` });\n} else {\n  const whole = await read({ path: `conflict://${entry.id}` });\n}","typeGuard":"function supportsBaseScope(entry) {\n  return entry.baseLines !== undefined && entry.baseLine !== undefined;\n}","tryCatchPattern":"try {\n  const base = await read({ path: `conflict://${id}/base` });\n} catch (err) {\n  if (String(err?.message).includes('has no base section')) {\n    const whole = await read({ path: `conflict://${id}` }); // 2-way fallback\n  } else throw err;\n}","preventionTips":["Check baseLines/baseLine on the conflict entry before requesting /base.","Enable git config merge.conflictStyle=diff3 if base sections are needed.","Write scope-iterating code that skips base for 2-way conflicts.","Prefer reading the whole conflict (no scope) when style is unknown."],"tags":["conflict-resolution","merge-conflict","diff3","scope"],"backgroundTag":"missing-base-section","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}