{"record":{"id":"dbd479080ffd6ca2","repo":"can1357/oh-my-pi","slug":"operation-operationnumber-mixes-inline-and-bare","errorCode":null,"errorMessage":"Operation ${operationNumber} mixes inline and bare selections. Use ⟪old|new⟫ for every selection, or use a » rewrite for all bare selections.","messagePattern":"Operation (.+?) mixes inline and bare selections\\. Use ⟪old\\|new⟫ for every selection, or use a » rewrite for all bare selections\\.","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/coding-agent/src/edit/sloppy.ts","lineNumber":683,"sourceCode":"\t\t\tsawBare = true;\n\t\t\tpatternText += pattern.slice(index, close + SELECT_CLOSE.length);\n\t\t} else {\n\t\t\tsawInline = true;\n\t\t\tif (selected.indexOf(SELECT_DIVIDER, divider + SELECT_DIVIDER.length) === -1) {\n\t\t\t\tpatternText += `${SELECT_OPEN}${selected.slice(0, divider)}${SELECT_CLOSE}`;\n\t\t\t\treplacements.push(selected.slice(divider + SELECT_DIVIDER.length));\n\t\t\t} else {\n\t\t\t\tconst resolved = resolveLiteralDividers(selected, operationNumber);\n\t\t\t\tpatternText += `${SELECT_OPEN}${resolved.old}${SELECT_CLOSE}`;\n\t\t\t\treplacements.push(resolved.desired);\n\t\t\t\tnotes.push(resolved.note);\n\t\t\t}\n\t\t}\n\t\tindex = close + SELECT_CLOSE.length;\n\t}\n\n\tif (sawBare && sawInline) {\n\t\tthrow new Error(\n\t\t\t`Operation ${operationNumber} mixes inline and bare selections. Use ${SELECT_OPEN}old${SELECT_DIVIDER}new${SELECT_CLOSE} for every selection, or use a ${REWRITE_HEADER} rewrite for all bare selections.`,\n\t\t);\n\t}\n\treturn { patternText, replacements, notes };\n}\n\n/**\n * Embed selection-only lines into the anchor line above them. Models write\n * `anchorLine` then `⟪old│new⟫` on the next line to mean \"change old inside\n * that anchor\"; literally the selection would match the next occurrence\n * below instead. Relocates only when old occurs exactly once in the anchor.\n */\nfunction relocateSelectionLines(patternText: string): string {\n\tconst lines = patternText.split(\"\\n\");\n\tfor (let index = 1; index < lines.length; index++) {\n\t\tconst previous = lines[index - 1];\n\t\tconst only = lines[index].trim().match(/^⟪([^⟪⟫]*)⟫$/u);\n\t\tif (!only || previous.includes(SELECT_OPEN) || previous.includes(GAP) || previous.trim() === \"\") continue;","sourceCodeStart":665,"sourceCodeEnd":701,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/coding-agent/src/edit/sloppy.ts#L665-L701","documentation":"Within one operation, selections must use a single style: either every selection is inline '⟪old│new⟫' (sawInline) or every selection is bare '⟪…⟫' whose replacement comes from a » rewrite block (sawBare). Mixing both styles in one operation is ambiguous and rejected.","triggerScenarios":"An operation contains at least one ⟪old│new⟫ inline selection and at least one bare ⟪text⟫ selection (no │ divider) in the same pattern.","commonSituations":"An LLM merges two edits into one operation, using inline for one change and bare+rewrite for another; a │ divider is accidentally dropped from one selection, turning it bare and tripping the mix check.","solutions":["Convert all selections to inline ⟪old│new⟫ form within the operation","Or move all replacements into a » rewrite block and make every selection bare","Restore the missing │ divider if one selection was meant to be inline"],"exampleFix":"// before\n«x ⟪a│b⟫ ⟪c⟫»y\n// after\n«x ⟪a│b⟫ ⟪c│y⟫»","handlingStrategy":"validation","validationCode":"const selections = pattern.match(/⟪[^⟫]*⟫/gu) ?? [];\nconst hasInline = selections.some(s => s.includes('│'));\nconst hasBare = selections.some(s => !s.includes('│'));\nif (hasInline && hasBare) throw new Error('mixed inline and bare selections in one operation');","typeGuard":null,"tryCatchPattern":"try {\n  applySloppy(content, input, ctx);\n} catch (err) {\n  if (err instanceof Error && err.message.includes('mixes inline and bare selections')) {\n    // normalize all selections to one style and re-send\n  } else throw err;\n}","preventionTips":["Pick one selection style per operation: all inline ⟪old│new⟫ or all bare with a » rewrite","Check that every intended inline selection contains the │ divider","Keep edits with different styles in separate operations"],"tags":["sloppy","selection-markers","consistency"],"backgroundTag":"mixed-selection-styles","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}