Skip to content

fix(templates): don't leak stray whitespace from over-indented trailing blank lines - #1986

Open
BenAyedMedAla wants to merge 1 commit into
dottxt-ai:mainfrom
BenAyedMedAla:fix/template-trailing-blank-line-whitespace
Open

fix(templates): don't leak stray whitespace from over-indented trailing blank lines#1986
BenAyedMedAla wants to merge 1 commit into
dottxt-ai:mainfrom
BenAyedMedAla:fix/template-trailing-blank-line-whitespace

Conversation

@BenAyedMedAla

Copy link
Copy Markdown

Fixes #1985.

What

build_template_from_string (used by Template.from_string/Template.from_file and by Application) is supposed to collapse any trailing blank line(s) in a template down to exactly one trailing linebreak. That only worked when the trailing blank line's indentation was pure spaces no deeper than the template's common margin — a more deeply indented, or tab-indented, trailing blank line leaked extra blank lines and stray whitespace straight into the rendered prompt instead.

Root cause

  • inspect.cleandoc only fully empties a trailing whitespace-only line when its (tab-expanded) indentation is <= the common margin computed from the rest of the content; otherwise it leaves a non-empty leftover line rather than dropping it.
  • The existing ends_with_linebreak heuristic (content.replace(" ", "").endswith("\n\n")) only accounts for literal space characters, so it couldn't detect the blank line in the tab case either, even when cleandoc did clean it up.

See #1985 for the full analysis and a minimal repro.

Fix

  • .rstrip() cleandoc's output before conditionally restoring a single trailing linebreak, so any leftover whitespace-only tail is removed regardless of why cleandoc left it behind.
  • Broaden the "did the original content end in a blank line" check to strip all horizontal whitespace (not just " "), so tabs are handled the same as spaces.

Both changes are scoped to build_template_from_string; Template.from_file shares the same dedent/whitespace-collapse tail so it benefits too, but the fix lives entirely in the string path since that's where the bug is (via cleandoc+heuristic), not in file-specific logic.

Tests

Added two regression tests mirroring the existing test_template_from_str_with_extra_linebreaks case:

  • test_render_over_indented_trailing_blank_line_collapses_to_one_linebreak
  • test_render_tab_indented_trailing_blank_line_collapses_to_one_linebreak

Ran locally: tests/test_templates.py (19/19) and tests/test_applications.py (6/6) pass. ruff check (pinned 0.9.1, project config) and mypy (pinned 1.14.1, --allow-redefinition) are clean on both changed files.


  • We should be able to understand what the PR does from its title only
  • There is a high-level description of the changes
  • If I add a new feature, there is an issue discussing it already — N/A, this is a bug fix with its own issue (Template.from_string leaks stray blank lines/whitespace when a trailing blank line is over-indented or tab-indented #1985)
  • There are links to all the relevant issues, discussions and PRs
  • The branch is rebased on the latest main commit
  • Commit messages follow the linked guidelines
  • One commit per logical change
  • The code respects the current naming conventions
  • Docstrings follow the numpy style guide — N/A, no docstring changes
  • pre-commit is installed and configured on my machine, and I ran the equivalent checks (pinned ruff/mypy) before opening this PR
  • There are tests covering the changes
  • The documentation is up-to-date — N/A, no user-facing docs reference this internal helper's exact whitespace behavior

This PR was developed with the help of an AI coding assistant (Claude Code); I've read and understand every line of the diff, and ran the tests/lint/type-checks myself before opening this.

…ng blank lines

`build_template_from_string` collapses trailing blank lines in a template
down to a single linebreak, but only worked when the trailing blank line's
indentation was pure spaces no deeper than the template's common margin.

`inspect.cleandoc` only fully empties a trailing whitespace-only line when
its (tab-expanded) indentation is <= that margin; a more deeply indented or
tab-indented trailing blank line is left behind as a non-empty leftover
line instead of being dropped. The existing `ends_with_linebreak` check
also only stripped literal spaces from the raw content, so it couldn't
detect the blank line in the tab case either. The combination leaked extra
blank lines and stray trailing whitespace straight into rendered prompts.

Strip cleandoc's own leftover whitespace explicitly, and broaden the
blank-line detection to any horizontal whitespace, not just spaces.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Template.from_string leaks stray blank lines/whitespace when a trailing blank line is over-indented or tab-indented

1 participant