vxcontrol/pentagi · warning

diff is required and cannot be empty

Error message

diff is required and cannot be empty

What it means

Input validation error from EditFile (backend/pkg/tools/terminal.go): the unified 'diff' argument is empty or whitespace-only, so no edit can be applied. The LLM/tool caller must supply a non-empty unified diff; the file is left untouched.

Source

Thrown at backend/pkg/tools/terminal.go:507

		AllowOverwriteDirWithFile: true,
	})
	if err != nil {
		return fmt.Errorf("container file transfer failed: %w", err)
	}

	return nil
}

// EditFile applies a unified diff to the file at path: it reads the current
// content, applies the diff to it entirely in memory (see applyUnifiedDiff),
// and only if every hunk applied cleanly writes the result back - a diff
// that doesn't fully apply leaves the file untouched.
func (t *terminal) EditFile(ctx context.Context, flowID int64, path, diffText string) (string, error) {
	if path == "" {
		return "", fmt.Errorf("path is required and cannot be empty")
	}
	if strings.TrimSpace(diffText) == "" {
		return "", fmt.Errorf("diff is required and cannot be empty")
	}

	current, err := t.readFileFromContainer(ctx, flowID, path)
	if err != nil {
		return "", fmt.Errorf("failed to read current content of %s before editing: %w", path, err)
	}

	newContent, hunksApplied, err := ApplyUnifiedDiff(current, diffText)
	if err != nil {
		return "", fmt.Errorf("failed to apply diff to %s: %w", path, err)
	}

	if err := t.writeFileToContainer(ctx, flowID, path, newContent); err != nil {
		return "", fmt.Errorf("failed to write edited content of %s: %w", path, err)
	}

	successMsg := fmt.Sprintf("Applied %d diff hunk(s) to %s (%d -> %d bytes)", hunksApplied, path, len(current), len(newContent))
	styledMsg := fmt.Sprintf("%s%s%s%s", ansiColorSystemMsg, successMsg, ansiColorReset, ansiLineTerminator)

View on GitHub (pinned to ea665308ba)

Solutions

  1. Provide a valid unified diff (---/+++ headers plus @@ hunks) in the diffText argument
  2. If no changes are needed, do not call EditFile at all — skip the call or use WriteFile for full rewrites
  3. Validate diffText is non-blank in the caller before dispatching (strings.TrimSpace check)
  4. If the model repeatedly emits empty diffs, improve the tool description/prompt requiring a unified diff body

Example fix

// before
msg, err := term.EditFile(ctx, flowID, path, diff)
// after
if strings.TrimSpace(diff) == "" {
    return fmt.Errorf("refusing to call EditFile with empty diff for %s", path)
}
msg, err := term.EditFile(ctx, flowID, path, diff)
Defensive patterns

Strategy: validation

Validate before calling

if strings.TrimSpace(diffText) == "" {
    return fmt.Errorf("diffText must contain a unified diff before calling edit_file")
}
if !strings.Contains(diffText, "@@") {
    return fmt.Errorf("diffText does not look like a unified diff (no hunk headers)")
}

Type guard

func nonBlank(s string) bool { return strings.TrimSpace(s) != "" }

Try / catch

msg, err := term.EditFile(ctx, flowID, path, diff)
if err != nil && strings.Contains(err.Error(), "diff is required") {
    return fmt.Errorf("edit_file called with empty diff; skipping no-op edit")
}

Prevention

When it happens

Trigger: Calling EditFile with diffText="" or a string containing only spaces/newlines — e.g. the model emitted no diff body, or the caller passed the wrong variable.

Common situations: LLM tool call where the model produced an explanation but no diff; upstream diff generation returned an empty string on no-change; callers using EditFile to 'touch' a file instead of WriteFile.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


AI-assisted analysis of vxcontrol/pentagi@ea665308ba (2026-09-01). Data as JSON: /api/errors/b56eb6e3e099e319. Report an issue: GitHub.