fix(edit): point empty-replace error at operation=delete

A replace with empty new_content failed with a bare 'new_content is required' message, leaving the model to guess. Append a hint to use operation=delete when the intent is removal. Adds TestValidateReplaceEmptySuggestsDelete.
This commit is contained in:
2026-06-20 00:33:31 +01:00
parent b0c1fc0480
commit 5827290ece
2 changed files with 21 additions and 1 deletions
+5 -1
View File
@@ -270,7 +270,11 @@ func (e *Engine) validateBaseEdit(edit *ASTEdit) error {
switch edit.Operation {
case EditReplace, EditInsertBefore, EditInsertAfter:
if edit.NewContent == "" {
return errors.NewInvalidEditError(fmt.Sprintf("new_content is required for %s operation", edit.Operation))
msg := fmt.Sprintf("new_content is required for %s operation", edit.Operation)
if edit.Operation == EditReplace {
msg += " (to remove content instead, use operation=delete)"
}
return errors.NewInvalidEditError(msg)
}
case EditDelete:
// new_content not required
+16
View File
@@ -101,6 +101,22 @@ func TestValidateEdit(t *testing.T) {
}
}
// A replace with empty new_content should point the caller at operation=delete.
func TestValidateReplaceEmptySuggestsDelete(t *testing.T) {
e := NewEngine(parser.NewRegistry())
err := e.validateASTEdit(&ASTEdit{
File: "test.go",
Operation: EditReplace,
Selector: ASTSelector{Kind: "function_declaration"},
})
if err == nil {
t.Fatal("expected error for replace with empty new_content")
}
if !strings.Contains(err.Error(), "operation=delete") {
t.Errorf("error should suggest operation=delete, got: %v", err)
}
}
func TestResolveSelector(t *testing.T) {
registry := parser.NewRegistry()
defer registry.Close()