Aider-AI/aider · error · ValueError

Error applying action

Error message

Error applying action '{action.type}' to {action.path}: {e}

What it means

Wrapper: apply_edits catches DiffError, FileNotFoundError, IOError, and OSError raised while applying one action and re-raises as ValueError with the action type, path, and original message. The ValueError convention matches other coders' failure signaling, so callers only handle one exception type.

Solutions

  1. Parse the embedded cause (action type + path) from the message and fix that specific condition, then re-apply
  2. Verify filesystem state afterward — actions before the failing one were already applied
  3. Restore/checkpoint the repo (git status) before retrying to avoid double-application
Defensive patterns

Strategy: try-catch

Try / catch

try:
    coder.apply_edits(edits)
except ValueError as e:
    # message shape: "Error applying action '<TYPE>' to <path>: <cause>"
    import re
    m = re.match(r"Error applying action '(\w+)' to (.*): (.*)", str(e), re.S)
    if m:
        action_type, path, cause = m.groups()
        log.warning("apply failed for %s on %s: %s", action_type, path, cause)
    raise

Prevention

When it happens

Trigger: Any per-action failure (add-exists, update-missing, chunk mismatch, IO error) inside apply_edits; the message embeds the underlying DiffError text such as 'UPDATE Error: File does not exist: x.py'.

Common situations: Callers of coder.apply_edits (GUI, tests, automation) catching ValueError to detect failed patch application; partial application — earlier actions in the loop may already have been written.

Related errors


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

Appendix: source

Thrown at aider/coders/patch_coder.py:635

                            )
                    else:
                        self.io.tool_output(f"Updating {action.path}")

                    # 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

View on GitHub (pinned to 5dc9490bb3)