langchain-ai/deepagents · error · ValueError
ReadResult.total_lines ({self.total_lines}) cannot be less t
Error message
ReadResult.total_lines ({self.total_lines}) cannot be less than end_line ({self.end_line}) What it means
ReadResult.__post_init__ requires that when both the window and total_lines are present, total_lines >= end_line. The last line shown cannot be beyond the end of the file, so a result claiming, say, end_line=50 of a file with total_lines=30 is internally inconsistent and rejected with a ValueError. This keeps pagination invariants (total covers the window) intact for consumers.
Source
Thrown at libs/deepagents/deepagents/backends/protocol.py:271
):
msg = "ReadResult.no_lines_requested describes an uninspected window; it cannot be combined with error or pagination fields"
raise ValueError(msg)
if self.next_offset is not None and self.start_line is None:
msg = "ReadResult.next_offset requires start_line and end_line to be set"
raise ValueError(msg)
if self.total_lines is not None and self.start_line is None:
msg = "ReadResult.total_lines requires start_line and end_line to be set"
raise ValueError(msg)
# Numeric consistency of a present window. `start_line`/`end_line` are
# bound together above, so testing `start_line` covers both.
if self.start_line is not None and self.end_line is not None:
if self.start_line < 1 or self.end_line < self.start_line:
msg = f"ReadResult window must satisfy 1 <= start_line <= end_line, got start_line={self.start_line}, end_line={self.end_line}"
raise ValueError(msg)
if self.total_lines is not None and self.total_lines < self.end_line:
msg = f"ReadResult.total_lines ({self.total_lines}) cannot be less than end_line ({self.end_line})"
raise ValueError(msg)
if self.next_offset is not None and self.next_offset != self.end_line:
msg = f"ReadResult.next_offset ({self.next_offset}) must equal end_line ({self.end_line}), the 0-indexed line after the last shown"
raise ValueError(msg)
@dataclass
class WriteResult:
"""Result from backend `write` operations.
Attributes:
error: Error message on failure, `None` on success.
path: Absolute path of written file, `None` on failure.
Examples:
>>> WriteResult(path="/f.txt")
>>> WriteResult(error="File exists")
"""
View on GitHub (pinned to a1af029e6e)
Solutions
- Compute total_lines from the full file (all lines), not just the returned window.
- Clamp or recompute end_line so it never exceeds total_lines when the requested window runs past EOF.
- Omit total_lines if the backend cannot reliably determine the full line count.
Example fix
// before return ReadResult(content=text, start_line=1, end_line=len(lines), total_lines=len(lines)) // after all_lines = full_file_text.splitlines() return ReadResult(content=text, start_line=1, end_line=len(lines), total_lines=len(all_lines))
Defensive patterns
Strategy: validation
Validate before calling
def check_total(end_line, total_lines):
if total_lines is not None and end_line is not None:
assert total_lines >= end_line, f'total_lines={total_lines} < end_line={end_line}' Type guard
def has_consistent_total(r) -> bool:
return r.total_lines is None or r.end_line is None or r.total_lines >= r.end_line Try / catch
try:
result = ReadResult(..., total_lines=total)
except ValueError:
result = ReadResult(...) # retry without total_lines Prevention
- Compute total_lines from the full file content, never from the returned window.
- Clamp end_line to total_lines when a requested window extends past EOF.
- Avoid caching total line counts across writes/edits to the same file.
When it happens
Trigger: Constructing ReadResult where total_lines is computed from a truncated/partial count while end_line reflects a larger window — e.g. counting only the lines in the returned content instead of the whole file, or hardcoding a stale total after the file shrank.
Common situations: Custom backends computing total_lines from len(content.splitlines()) of the returned window instead of the full file; caching total counts across edits; unit-test fixtures with mismatched numbers.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- ReadResult.next_offset ({self.next_offset}) must equal end_l
- ReadResult.total_lines requires start_line and end_line to b
- ReadResult window must satisfy 1 <= start_line <= end_line,
- modes can only be provided when agent is a factory
- models can only be provided when agent is a factory
AI-assisted analysis of langchain-ai/deepagents@a1af029e6e (2026-08-29).
Data as JSON: /api/errors/70bf7cbdf8a297b7.
Report an issue: GitHub.