microsoft/autogen · error · ValueError

Empty patch text provided.

Error message

Empty patch text provided.

What it means

After parsing the patch text with unidiff, an empty PatchSet means the text contained no file diffs (blank string, whitespace, or a diff with no headers/hunks). apply_patch raises rather than creating a no-op revision.

Source

Thrown at python/packages/autogen-ext/src/autogen_ext/memory/canvas/_text_canvas.py:159

        Uses the *unidiff* library to accurately apply hunks and validate context lines.
        """
        if isinstance(patch_data, bytes):
            patch_data = patch_data.decode("utf-8")
        if not isinstance(patch_data, str):
            raise ValueError(f"Expected str or bytes, got {type(patch_data)}")
        self._ensure_file(filename)
        original_content = self.get_latest_content(filename)

        if PatchSet is None:
            raise ImportError(
                "The 'unidiff' package is required for patch application. Install with 'pip install unidiff'."
            )

        patch = PatchSet(patch_data)
        # Our canvas stores exactly one file per patch operation so we
        # use the first (and only) patched_file object.
        if not patch:
            raise ValueError("Empty patch text provided.")
        patched_file = patch[0]
        working_lines = original_content.splitlines(keepends=True)
        line_offset = 0
        for hunk in patched_file:
            # Calculate the slice boundaries in the *current* working copy.
            start = hunk.source_start - 1 + line_offset
            end = start + hunk.source_length
            # Build the replacement block for this hunk.
            replacement: List[str] = []
            for line in hunk:
                if line.is_added or line.is_context:
                    replacement.append(line.value)
                # removed lines (line.is_removed) are *not* added.
            # Replace the slice with the hunk‑result.
            working_lines[start:end] = replacement
            line_offset += len(replacement) - (end - start)
        new_content = "".join(working_lines)

View on GitHub (pinned to 027ecf0a37)

Solutions

  1. Skip the call when the patch text is blank: if not patch_data.strip(): return.
  2. If a diff was expected, verify the text contains '--- a/...' and '+++ b/...' headers and at least one '@@' hunk.
  3. Fix the prompt/tool schema so the model returns well-formed unified diffs.

Example fix

# before
canvas.apply_patch("f.txt", patch_text)
# after
if patch_text and patch_text.strip():
    canvas.apply_patch("f.txt", patch_text)
Defensive patterns

Strategy: validation

Validate before calling

if not patch_text or not patch_text.strip():
    # nothing to apply — skip instead of erroring
    pass
else:
    assert "@@" in patch_text, "patch text has no hunks; not a valid unified diff"
    canvas.apply_patch(filename, patch_text)

Type guard

def is_nonempty_unified_diff(text: str) -> bool:
    return isinstance(text, str) and bool(text.strip()) and "@@" in text

Try / catch

try:
    canvas.apply_patch(filename, patch_text)
except ValueError as e:
    if "Empty patch text" in str(e):
        pass  # no-op patch from the model; skip
    else:
        raise

Prevention

When it happens

Trigger: Calling apply_patch(filename, ""), with only whitespace, or with text that is not valid unified-diff format (so unidiff parses zero files).

Common situations: LLM emitting an empty patch in a tool call; extracting the wrong field from a model response; copy/paste dropping the '---/+++' headers so unidiff recognizes nothing.

Related errors


AI-assisted analysis of microsoft/autogen@027ecf0a37 (2026-08-15). Data as JSON: /api/errors/2cf21b631f238d43. Report an issue: GitHub.