Aider-AI/aider · error · ValueError

Unexpected error applying action '{action.type}' to {action.

Error message

Unexpected error applying action '{action.type}' to {action.path}: {e}

What it means

Second, broader wrapper in apply_edits: an exception that is not DiffError/OS-level (e.g. TypeError, IndexError, AttributeError) escaped while applying an action. It signals a bug or unexpected data shape in the apply path, not a normal patch mismatch.

Source

Thrown at aider/coders/patch_coder.py:638

                    # Ensure parent directory exists for target
                    target_path_obj.parent.mkdir(parents=True, exist_ok=True)
                    self.io.write_text(target_full_path, new_content)

                    # Remove original file *after* successful write to new location if moved
                    if action.move_path and full_path != target_full_path:
                        path_obj.unlink()

                else:
                    # Should not happen
                    raise DiffError(f"Unknown action type encountered: {action.type}")

            except (DiffError, FileNotFoundError, IOError, OSError) as e:
                # Raise a ValueError to signal failure, consistent with other coders.
                raise ValueError(f"Error applying action '{action.type}' to {action.path}: {e}")
            except Exception as e:
                # Catch unexpected errors during application
                raise ValueError(
                    f"Unexpected error applying action '{action.type}' to {action.path}: {e}"
                )

    def _apply_update(self, text: str, action: PatchAction, path: str) -> str:
        """
        Applies UPDATE chunks to the given text content.
        Adapted from _get_updated_file in apply_patch.py.
        """
        if action.type is not ActionType.UPDATE:
            # Should not be called otherwise, but check for safety
            raise DiffError("_apply_update called with non-update action")

        orig_lines = text.splitlines()  # Use splitlines to handle endings consistently
        dest_lines: List[str] = []
        current_orig_line_idx = 0  # Tracks index in orig_lines processed so far

        # Sort chunks by their original index to apply them sequentially
        sorted_chunks = sorted(action.chunks, key=lambda c: c.orig_index)

View on GitHub (pinned to 5dc9490bb3)

Solutions

  1. Inspect the embedded exception message/type; if it's a TypeError/AttributeError, audit how the PatchAction and chunks were constructed
  2. Rebuild actions via the parser (parse a full patch text) instead of constructing them manually
  3. Report upstream if the actions came straight from parsed model output
Defensive patterns

Strategy: try-catch

Validate before calling

def actions_wellformed(actions) -> bool:
    for a in actions:
        if a.chunks is None or any(c is None for c in (a.chunks or [])):
            return False
        if a.type.name == "ADD" and not isinstance(a.new_content, str):
            return False
    return True

Try / catch

try:
    coder.apply_edits(edits)
except ValueError as e:
    if str(e).startswith("Unexpected error"):
        # capture full traceback — this is a bug, not a patch problem
        log.exception("apply_edits internal failure")
    raise

Prevention

When it happens

Trigger: Malformed chunks (None lines, negative indices) reaching _apply_update; unexpected None in new_content or chunks from hand-built PatchActions; regressions in helper functions raising arbitrary exceptions.

Common situations: Programmatic use of PatchCoder with custom-built actions; version mismatches after refactors; corrupt in-memory state after a failed parse is reused.

Related errors


AI-assisted analysis of Aider-AI/aider@5dc9490bb3 (2026-08-15). Data as JSON: /api/errors/1f5dd3229d928a59. Report an issue: GitHub.