Skip to content

Fix ParserSyntaxError line number off-by-one error - #1474

Open
hippi345 wants to merge 2 commits into
Instagram:mainfrom
hippi345:fix/parser-error-line-offset-1472
Open

hippi345 wants to merge 2 commits into
Instagram:mainfrom
hippi345:fix/parser-error-line-offset-1472

Conversation

@hippi345

Copy link
Copy Markdown

Fix ParserSyntaxError line number off-by-one error

Summary

Fixes #1472

The raw_line property in ParserSyntaxError is documented and treated as 1-based, but was being computed by adding 1 to an already 1-based line number from the parser. This caused several related bugs:

  1. Incorrect line numbers shown to users in error messages
  2. Tab adjustment logic using the wrong line to calculate column offsets, causing columns to be incorrectly clamped even when there are no tabs
  3. EOF clamping logic erroneously triggering on the last line of input, causing errors on the last line to be reported at column 1

Changes

Rust changes (native/libcst/src/parser/errors.rs):

  • Removed the +1 offset when passing line to raw_line (line 59)
  • Fixed EOF clamping check from line + 1 > lines.len() to line > lines.len() (line 51)
  • Fixed EOF clamping assignment from line = lines.len() - 1 to line = lines.len() (line 52)

Python changes (libcst/tests/test_exceptions.py):

  • Added regression test test_parser_error_line_numbers() that verifies:
    • Errors on the first line of multi-line input report raw_line=1
    • Errors on the last line report the correct line number
    • Both raw_line/raw_column and editor_line/editor_column are correct
    • Error messages display the correct location
  • Added regression test test_parser_error_tab_adjustment_on_correct_line() that verifies:
    • Tab adjustment uses the correct line to calculate column offsets
    • Tabs on other lines don't affect the error column position

Testing

All tests pass:

  • ✅ Rust tests: cargo test in native/ (all tests pass)
  • ✅ Python tests: uv run poe test (2163 tests pass, 14 skipped, 2 expected failures)
  • ✅ New regression tests verify both line numbers and caret positions

Before fix:

import libcst as cst

# Error on line 1
try:
    cst.parse_module("x = (1 2)\ny = 3\nz = 4\n")
except cst.ParserSyntaxError as e:
    print(f"raw_line={e.raw_line}, raw_column={e.raw_column}")
    # Output: raw_line=2, raw_column=8  � Wrong!
    print(str(e).splitlines()[0])
    # Output: Syntax Error @ 2:6.  � Wrong line and column!

# Error on line 2
try:
    cst.parse_module("x = 1\ny = (1 2)\n")
except cst.ParserSyntaxError as e:
    print(f"raw_line={e.raw_line}, raw_column={e.raw_column}")
    # Output: raw_line=2, raw_column=0  � Column clamped to 0!
    print(str(e).splitlines()[0])
    # Output: Syntax Error @ 2:1.  � Wrong column!

After fix:

import libcst as cst

# Error on line 1
try:
    cst.parse_module("x = (1 2)\ny = 3\nz = 4\n")
except cst.ParserSyntaxError as e:
    print(f"raw_line={e.raw_line}, raw_column={e.raw_column}")
    # Output: raw_line=1, raw_column=8  ✅ Correct!
    print(str(e).splitlines()[0])
    # Output: Syntax Error @ 1:9.  ✅ Correct!

# Error on line 2
try:
    cst.parse_module("x = 1\ny = (1 2)\n")
except cst.ParserSyntaxError as e:
    print(f"raw_line={e.raw_line}, raw_column={e.raw_column}")
    # Output: raw_line=2, raw_column=8  ✅ Correct!
    print(str(e).splitlines()[0])
    # Output: Syntax Error @ 2:9.  ✅ Correct!

Scope

This fix is scoped to the issue and only modifies:

  • The line number calculation in the Rust parser error conversion
  • The EOF clamping logic to work correctly with 1-based line numbers
  • Test coverage to prevent regression

The fix maintains backward compatibility with the Python API - raw_line and editor_line remain 1-based as documented, but now report the correct values.

The raw_line property is documented as 1-based but was incorrectly
computed by adding 1 to an already 1-based line number from the parser.
This caused:
- Incorrect line numbers shown to users
- Tab adjustment logic using the wrong line
- EOF clamping logic incorrectly triggering on the last line

Changes:
- Remove the +1 offset in native/libcst/src/parser/errors.rs
- Fix EOF clamping to check 'line > len' instead of 'line + 1 > len'
- Fix EOF clamping to set 'line = len' instead of 'line = len - 1'
- Add regression tests for line number and caret position accuracy

Fixes Instagram#1472
Test that parser errors reported past end-of-file are correctly
clamped to the last line with column 0, ensuring the EOF clamping
logic fixed in the previous commit works as intended.

Related to Instagram#1472
@meta-cla

meta-cla Bot commented Oct 15, 2026

Copy link
Copy Markdown

Hi @hippi345!

Thank you for your pull request and welcome to our community.

Action Required

In order to merge any pull request (code, docs, etc.), we require contributors to sign our Contributor License Agreement, and we don't seem to have one on file for you.

Process

In order for us to review and merge your suggested changes, please sign at https://code.facebook.com/cla. If you are contributing on behalf of someone else (eg your employer), the individual CLA may not be sufficient and your employer may need to sign the corporate CLA.

Once the CLA is signed, our tooling will perform checks and validations. Afterwards, the pull request will be tagged with CLA signed. The tagging process may take up to 1 hour after signing. Please give it that time before contacting us about it.

If you have received this in error or have any questions, please contact us at cla@meta.com. Thanks!

@hippi345
hippi345 marked this pull request as ready for review October 15, 2026 15:44
@meta-cla

meta-cla Bot commented Oct 15, 2026

Copy link
Copy Markdown

Thank you for signing our Contributor License Agreement. We can now accept your code for this (and any) Meta Open Source project. Thanks!

@meta-cla meta-cla Bot added the CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. label Oct 15, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ParserSyntaxError.raw_line is off by one

1 participant