{"record":{"id":"7e9900116c209b80","repo":"can1357/oh-my-pi","slug":"operation-operationnumber-has-no-visible-curren","errorCode":null,"errorMessage":"Operation ${operationNumber} has no visible current text.","messagePattern":"Operation (.+?) has no visible current text\\.","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/coding-agent/src/edit/sloppy.ts","lineNumber":1485,"sourceCode":"\treturn { text, starts, ends };\n}\n\nfunction patternGapAt(source: string, offset: number): string | undefined {\n\treturn source.startsWith(GAP, offset) ? GAP : undefined;\n}\n\nfunction patternContainsGap(source: string): boolean {\n\treturn source.includes(GAP);\n}\n\nfunction parsePattern(pattern: string, operationNumber: number): ParsedPattern {\n\tif (pattern.trim() === \"\") throw new Error(`Operation ${operationNumber} has an empty pattern.`);\n\tvalidateSelectionMarkers(pattern, operationNumber);\n\tconst hasGap = patternContainsGap(pattern);\n\tconst hasSelection = pattern.includes(SELECT_OPEN);\n\tif (!hasGap && !hasSelection) {\n\t\tconst normalized = normalizeText(pattern).text;\n\t\tif (normalized === \"\") throw new Error(`Operation ${operationNumber} has no visible current text.`);\n\t\treturn {\n\t\t\ttokens: [{ kind: \"literal\", text: pattern, normalized }],\n\t\t\tselectionStart: 0,\n\t\t\tselectionEnd: 1,\n\t\t\tinsertion: false,\n\t\t\tlineInsertion: false,\n\t\t\tselectedCaptureIndices: [],\n\t\t\tselectionRanges: [],\n\t\t\tselectionPairs: [],\n\t\t\tliteralFallback: undefined,\n\t\t};\n\t}\n\n\tconst tokens: PatternToken[] = [];\n\tlet literal = \"\";\n\tlet captureCount = 0;\n\tconst selectionBoundaries: number[] = [];\n\tconst selectionAtLineStart: boolean[] = [];","sourceCodeStart":1467,"sourceCodeEnd":1503,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/coding-agent/src/edit/sloppy.ts#L1467-L1503","documentation":"The sloppy-edit pattern parser rejects an operation whose pattern contains no gap marker (`...`) and no selection markers (`«` `»`), yet after normalizing (trimming indentation and whitespace) has no visible text left. Such a pattern carries no anchor content at all, so the library throws rather than try to match an empty literal against the file.","triggerScenarios":"Calling the sloppy edit operation with a pattern that is only whitespace, only comment markers, or only indentation between markers, without a `...` gap or `«...»` selection. E.g. pattern `\"   \"` or `\"//\"` passes the empty-pattern check but fails normalizeText producing an empty normalized string.","commonSituations":"Hand-copying a pattern that is purely indentation or blank lines from an editor; building patterns programmatically where the gap marker variable ends up empty; pasting a region where the intended anchor line is a whitespace-only line.","solutions":["Include actual visible code text in the pattern (e.g. a statement or identifier from the file).","If the pattern intentionally spans a region, add a `...` gap marker between the anchors.","If the pattern is meant to insert into a position, wrap the insertion point with selection markers `«` `»`."],"exampleFix":"// before\nconst pattern = \"   \";\n// after\nconst pattern = \"return computeTotal(items);\";","handlingStrategy":"validation","validationCode":"if (pattern.trim() !== \"\" && !/\\S/.test(pattern)) throw new Error(\"pattern has no visible text\");\n// simpler: ensure some non-whitespace, non-marker content exists before calling the edit API\nif (!/[\\p{L}\\p{N}_$]/u.test(pattern.replace(/«|»|\\.\\.\\./g, \"\"))) {\n  throw new Error(\"pattern must contain visible text, a gap (...), or a selection\");\n}","typeGuard":"function hasVisiblePatternText(pattern: string): boolean {\n  const stripped = pattern.replace(/«|»|\\.\\.\\./g, \"\");\n  return stripped.trim().length > 0;\n}","tryCatchPattern":"try {\n  await applySloppyEdit({ pattern });\n} catch (err) {\n  if (err instanceof Error && err.message.includes(\"no visible current text\")) {\n    // rebuild pattern with a real anchor line from the file\n  }\n  throw err;\n}","preventionTips":["Always anchor patterns on at least one real line copied from the file.","Never build patterns from whitespace-only or comment-only lines.","When generating patterns programmatically, assert the interpolated snippet is non-empty."],"tags":["edit-pattern","validation","sloppy-edit"],"backgroundTag":"empty-edit-pattern","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}