{"record":{"id":"7c8d3db60633b03e","repo":"can1357/oh-my-pi","slug":"put-startline-endline-rejected-a-select","errorCode":null,"errorMessage":"`PUT ${startLine}.=${endLine}:` rejected: a selected boundary row is required for the file to parse, but the body indentation does not establish whether it belongs before or after that row. Re-read the region and re-issue with a range that excludes every unchanged boundary row.","messagePattern":"`PUT (.+?)\\.=(.+?):` rejected: a selected boundary row is required for the file to parse, but the body indentation does not establish whether it belongs before or after that row\\. Re-read the region and re-issue with a range that excludes every unchanged boundary row\\.","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/hashline/src/apply.ts","lineNumber":798,"sourceCode":"\tif (path === undefined) return undefined;\n\n\tconst groups: { group: ReplacementGroup; variants: GroupVariant[] }[] = [];\n\tlet ambiguousGroup: ReplacementGroup | undefined;\n\tlet i = 0;\n\twhile (i < edits.length) {\n\t\tconst group = findReplacementGroup(edits, i);\n\t\tif (group) {\n\t\t\tconst built = buildGroupVariants(group, edits, fileLines, path, baselineParses);\n\t\t\tif (built.ambiguous && ambiguousGroup === undefined) ambiguousGroup = group;\n\t\t\tif (built.variants.length > 0) groups.push({ group, variants: built.variants });\n\t\t\ti = group.deleteIndices[group.deleteIndices.length - 1] + 1;\n\t\t} else {\n\t\t\ti++;\n\t\t}\n\t}\n\tif (groups.length === 0) {\n\t\tif (ambiguousGroup) {\n\t\t\tthrow new Error(ambiguousBoundaryPlacementMessage(ambiguousGroup.startLine, ambiguousGroup.endLine));\n\t\t}\n\t\treturn undefined;\n\t}\n\n\tlet combos: BoundaryCombo[] = [{ variants: [], touched: 0, kept: 0, dropped: 0 }];\n\tfor (const { variants } of groups) {\n\t\tconst next: BoundaryCombo[] = [];\n\t\tfor (const combo of combos) {\n\t\t\tnext.push({ ...combo, variants: [...combo.variants, null] });\n\t\t\tfor (const variant of variants) {\n\t\t\t\tnext.push({\n\t\t\t\t\tvariants: [...combo.variants, variant],\n\t\t\t\t\ttouched: combo.touched + 1,\n\t\t\t\t\tkept: combo.kept + variant.kept,\n\t\t\t\t\tdropped: combo.dropped + variant.dropped,\n\t\t\t\t});\n\t\t\t}\n\t\t}","sourceCodeStart":780,"sourceCodeEnd":816,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/hashline/src/apply.ts#L780-L816","documentation":"When a hashline PUT edit groups into zero boundary-combination groups, applyEdits cannot determine placement of an unchanged boundary row whose indentation is ambiguous. If such an ambiguous group was recorded, it throws the descriptive ambiguousBoundaryPlacementMessage telling the caller to re-read and re-issue with a range excluding unchanged boundary rows.","triggerScenarios":"Issuing a `PUT start.=end:` edit where the selected range includes a boundary row (first/last of a block) that is unchanged, and the body's indentation does not disambiguate whether that row belongs before or after the edited region — so no valid combination of boundary rows can be built.","commonSituations":"Model selecting an overly broad line range that spans an unchanged blank/indentation-only boundary row; editing a block whose first or last line shares indentation with surrounding code; stale line ranges after the file changed.","solutions":["Re-read the region and re-issue the PUT with a range that excludes every unchanged boundary row","Narrow the edit to only the lines that actually change","If the boundary row must change, include new content that makes its placement unambiguous","Use a different edit form (single-line PUT or full rewrite) when block boundaries are ambiguous"],"exampleFix":"// before\n`PUT 10.=20:` // includes unchanged boundary row 10, ambiguous indentation\n// after — re-read region, then exclude unchanged boundary line\n`PUT 11.=20:` // start after the unchanged boundary row","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  applyHashlinePut(start, end, body);\n} catch (e) {\n  if (e.message.includes(\"boundary row is required\")) {\n    // re-read region, re-issue with range excluding unchanged boundary rows\n  }\n}","preventionTips":["Exclude unchanged first/last boundary rows from PUT ranges","Keep edit ranges tight around changed lines only","Re-read the region before retrying after this error","Avoid ranges whose edge rows are blank or indentation-only lines"],"tags":["patching","ambiguity","hashline","editing"],"backgroundTag":"ambiguous-boundary-row-placement","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}