palantir / palantir/palantir-java-format

2.89.0: spurious 'unclosed string literal' errors when file contains long strings (>~97 chars) in chained method calls

Open
#1,680 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Java
Stars
907
Forks
101
Avg merge
1d 3h
Merged PRs (30d)
19

Description

Bug description

When a Java file contains string literals of ~97+ characters inside a chained method call (e.g. .execute("very long SQL...")), the formatter's parser corrupts its internal state and reports spurious unclosed string literal errors in subsequent methods of the same file — even on syntactically valid code. The error always points to column 30 of lines in the next method, making the root cause non-obvious.

Version

palantir-java-format 2.89.0

Minimal reproducer

Save the following as Repro.java and run palantir-java-format --palantir Repro.java:

class Repro {
    void test() throws Exception {
        try (var con = getConnection()) {
            con.createStatement()
                    .execute("ALTER DATABASE tempdb MODIFY FILE (NAME = 'tempdev', FILENAME = 'D:\\tempDb\\DATA\\tempdb.mdf')");
            con.createStatement()
                    .execute("ALTER DATABASE tempdb MODIFY FILE (NAME = 'templog', FILENAME = 'D:\\tempDb\\DATA\\templog.ldf')");
            con.createStatement()
                    .execute("ALTER DATABASE tempdb MODIFY FILE (NAME = 'temp2', FILENAME = 'D:\\tempDb\\DATA\\tempdb_mssql_2.ndf')");
        }
    }

    void anotherMethod() {
        System.out.println("This method is valid but the formatter reports errors here");
    }

    java.sql.Connection getConnection() throws Exception { return null; }
}

Actual output

Repro.java:14:30: error: unclosed string literal
Repro.java:18:30: error: unclosed string literal
Repro.java:22:30: error: unclosed string literal

Lines 14, 18, 22 correspond to anotherMethod() and the getConnection() method — not to the lines with the long strings. The errors reference column 30, which has no relationship to the actual string content.

Expected output

Formatted Java output, exit code 0 — the file is syntactically valid Java.

Workaround

Split the long string literals with concatenation so each part is under ~97 characters:

con.createStatement()
        .execute("ALTER DATABASE tempdb MODIFY FILE"
                + " (NAME = 'tempdev', FILENAME = 'D:\\tempDb\\DATA\\tempdb.mdf')");

Notes

  • The 2.50.0 did not exhibit the bug.
  • The errors point to the wrong lines (subsequent methods, not the offending strings).
  • The threshold appears to be approximately 97 characters of string content when the string is an argument to a chained method call with ~20 characters of preceding indentation.
  • Verified on macOS ARM64, Java 17 (Zulu 17.64.17).

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Save the supplied reproducer as Repro.java and run palantir-java-format --palantir Repro.java to confirm the spurious errors after the long chained-call strings. Trace the formatter parser from this command and compare behavior with the reported 2.50.0 version. Done means valid Java formats successfully with exit code 0 and no errors in subsequent methods.

Written by the indexing model from the issue text.

Assessment

Tech stack
java
Domain
tooling
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
68/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.