Aider-AI/aider · error · ValueError
Invalid line_endings value: {line_endings}. Must be one of:
Error message
Invalid line_endings value: {line_endings}. Must be one of: {', '.join(valid_line_endings)} What it means
InputOutput.__init__ in aider/io.py validates the line_endings constructor argument against a whitelist {"platform", "lf", "crlf"}. Any other value — including None (unless you match the exact strings), typos like 'CRLF', 'windows', or 'auto' — raises ValueError at construction time, before any I/O happens. The chosen value is later mapped to self.newline (None for platform, \n for lf, \r\n for crlf) which controls how chat/input history files are written.
Source
Thrown at aider/io.py:326
self.yes = yes
self.input_history_file = input_history_file
if self.input_history_file:
try:
Path(self.input_history_file).parent.mkdir(parents=True, exist_ok=True)
except (PermissionError, OSError) as e:
self.tool_warning(f"Could not create directory for input history: {e}")
self.input_history_file = None
self.llm_history_file = llm_history_file
if chat_history_file is not None:
self.chat_history_file = Path(chat_history_file)
else:
self.chat_history_file = None
self.encoding = encoding
valid_line_endings = {"platform", "lf", "crlf"}
if line_endings not in valid_line_endings:
raise ValueError(
f"Invalid line_endings value: {line_endings}. "
f"Must be one of: {', '.join(valid_line_endings)}"
)
self.newline = (
None if line_endings == "platform" else "\n" if line_endings == "lf" else "\r\n"
)
self.dry_run = dry_run
current_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
self.append_chat_history(f"\n# aider chat started at {current_time}\n\n")
self.prompt_session = None
self.is_dumb_terminal = is_dumb_terminal()
if self.is_dumb_terminal:
self.pretty = False
fancy_input = False
View on GitHub (pinned to 5dc9490bb3)
Solutions
- Pass exactly one of the three accepted strings: 'platform' (use OS default), 'lf', or 'crlf'.
- If the value comes from user config, normalize it first: strip whitespace and lowercase it, then check membership before constructing InputOutput.
- Map platform names explicitly: 'Windows' -> 'crlf', 'Linux'/'Darwin' -> 'lf', or just use 'platform' to defer to the OS default.
Example fix
# before
io = InputOutput(line_endings="CRLF") # ValueError: Invalid line_endings value
# after
raw = "CRLF".strip().lower()
line_endings = raw if raw in {"platform", "lf", "crlf"} else "platform"
io = InputOutput(line_endings=line_endings) Defensive patterns
Strategy: validation
Validate before calling
VALID = {"platform", "lf", "crlf"}
def make_io(line_endings):
key = str(line_endings).strip().lower()
if key not in VALID:
raise ValueError(f"line_endings must be one of {sorted(VALID)}, got {line_endings!r}")
from aider.io import InputOutput
return InputOutput(line_endings=key) Type guard
def is_valid_line_endings(v) -> bool:
return isinstance(v, str) and v.strip().lower() in {"platform", "lf", "crlf"} Try / catch
try:
io = InputOutput(line_endings=le)
except ValueError as e:
if "Invalid line_endings" in str(e):
io = InputOutput(line_endings="platform") # safe default
else:
raise Prevention
- Centralize the normalization (lowercase + membership check) at whatever boundary accepts user config.
- Map platform identifiers explicitly ('Windows'->'crlf', else 'lf') or just use 'platform'.
- Write a unit test asserting every config enum value you support maps into {'platform','lf','crlf'}.
When it happens
Trigger: Instantiating InputOutput(line_endings=...) with a string outside the set {'platform','lf','crlf'}. Typical offenders: 'CRLF' (uppercase), 'LF', '\r\n', 'windows', 'unix', 'native', or passing an int/None where a string is expected. It raises immediately in __init__, so the failure occurs at object creation, not during file writes.
Common situations: Programmatically embedding aider's IO class in another tool and deriving line_endings from a config enum (e.g. LineEndings.CRLF.name yielding 'CRLF') or from platform.system() output ('Windows' instead of 'crlf'). Interactive CLI users rarely hit it because aider's own args pass one of the three valid literals.
Related errors
- Unknown edit format {edit_format}. Valid formats are: {', '.
- Error loading model settings from {model_settings_fname}: {e
- Error loading model definition from {model_fname}: {e}
- Messages don't properly alternate user/assistant: {turns}
- Unsupported audio format: {audio_format}
AI-assisted analysis of Aider-AI/aider@5dc9490bb3 (2026-08-15).
Data as JSON: /api/errors/5dd686796081a14c.
Report an issue: GitHub.