Skip to content

Quick fix "Add throws declaration" removes backslashes and qute fragments #4314

Closed

Description

@LukasLeppich

There are some unwanted changes made by the "Add throws declaration" Quick fix action.

If you use the QuickFix action Add throws declarat... the java extension will remove the fragment name of the second Template specification and the escaped backslashes from the string.

Before executing the QuickFix:

    String someString = "Escaped\\Test\\Path";

    @CheckedTemplate
    static class Templates {
        public static native TemplateInstance page();
        public static native TemplateInstance page$content();
    }

After performing the QuickFix:

    String someString = "Escaped\Test\Path";

    @CheckedTemplate
    static class Templates {
        public static native TemplateInstance page();
        public static native TemplateInstance page();
    }

Steps to reproduce:

  1. Clone reproducer repository: https://github.com/LukasLeppich/vscode-java-quickfix-bug
  2. Create a new VSCode Profile
  3. Install the Extension Pack for Java extension
  4. Open the SomePage.java class and perform the Add throws declarat... Quick Fix on line 30 service.test();

Tested with the following setup:

Vscode:
Version: 1.108.1 (user setup)
Commit: 585eba7c0c34fd6b30faac7c62a42050bfbc0086
Date: 2026-01-14T14:55:44.241Z

Extensions:
redhat.java@1.51.0
vscjava.vscode-gradle@3.17.2
vscjava.vscode-java-debug@0.58.5
vscjava.vscode-java-dependency@0.27.0
vscjava.vscode-java-pack@0.30.5
vscjava.vscode-java-test@0.44.0
vscjava.vscode-maven@0.45.1

Activity

  1. added theissue type on Jan 21, 2026
  2. fbricon commented on Jan 21, 2026

    @fbricon
    Collaborator

    Can't reproduce it in Eclipse IDE, meaning it's a bug in JDT.LS

  3. fbricon commented on Jan 21, 2026

    @fbricon
    Collaborator

    When resolving the code action, the server returns

    [Trace - 10:57:51 AM] Received response 'codeAction/resolve - (665)' in 9ms.
    Result: {
        "title": "Add throws declaration",
        "kind": "quickfix",
        "diagnostics": [
            {
                "range": {
                    "start": {
                        "line": 28,
                        "character": 8
                    },
                    "end": {
                        "line": 28,
                        "character": 22
                    }
                },
                "severity": 1,
                "code": "16777384",
                "source": "Java",
                "message": "Unhandled exception type ExecutionException"
            }
        ],
        "edit": {
            "changes": {},
            "documentChanges": [
                {
                    "textDocument": {
                        "version": null,
                        "uri": "file:///Users/fbricon/Dev/souk/quickfix-bug/src/main/java/org/acme/SomePage.java"
                    },
                    "edits": [
                        {
                            "snippet": {
                                "value": "import java.util.concurrent.ExecutionException;\n\nimport io.quarkus.qute.CheckedTemplate;\nimport io.quarkus.qute.TemplateInstance;\nimport jakarta.ws.rs.GET;\nimport jakarta.ws.rs.Path;\nimport jakarta.ws.rs.Produces;\nimport jakarta.ws.rs.core.MediaType;\n\n@Path(\"/some-page\")\npublic class SomePage {\n    \n    String someString = \"Escaped\\\\Test\\\\Path\";\n\n    static class Templates {\n        public static native TemplateInstance page();\n        public static native TemplateInstance page$content();\n    }\n    \n    private Service service;\n    public SomePage() {\n    }\n\n    @GET\n    @Produces(MediaType.TEXT_HTML)\n    public TemplateInstance get() throws ${1|ExecutionException,Exception,Throwable|}"
                            },
                            "range": {
                                "start": {
                                    "line": 4,
                                    "character": 0
                                },
                                "end": {
                                    "line": 27,
                                    "character": 33
                                }
                            },
                            "newText": ""
                        }
                    ]
                }
            ]
        }
    }
    

    I suspect that, because it's a snippet, VS Code goes through another pass at unescaping backslashes and dollar signs, and ends up applying

    
    [Trace - 10:57:51 AM] Sending notification 'textDocument/didChange'.
    Params: {
        "textDocument": {
            "uri": "file:///Users/fbricon/Dev/souk/quickfix-bug/src/main/java/org/acme/SomePage.java",
            "version": 66
        },
        "contentChanges": [
            {
                "range": {
                    "start": {
                        "line": 4,
                        "character": 0
                    },
                    "end": {
                        "line": 27,
                        "character": 33
                    }
                },
                "rangeLength": 593,
                "text": "import java.util.concurrent.ExecutionException;\n\nimport io.quarkus.qute.CheckedTemplate;\nimport io.quarkus.qute.TemplateInstance;\nimport jakarta.ws.rs.GET;\nimport jakarta.ws.rs.Path;\nimport jakarta.ws.rs.Produces;\nimport jakarta.ws.rs.core.MediaType;\n\n@Path(\"/some-page\")\npublic class SomePage {\n    \n    String someString = \"Escaped\\Test\\Path\";\n\n    static class Templates {\n        public static native TemplateInstance page();\n        public static native TemplateInstance page();\n    }\n    \n    private Service service;\n    public SomePage() {\n    }\n\n    @GET\n    @Produces(MediaType.TEXT_HTML)\n    public TemplateInstance get() throws ExecutionException"
            }
        ]
    }
    
  4. fbricon commented on Jan 21, 2026

    @fbricon
    Collaborator

    I tried opening the same project in LazyVim and code action was properly applied there. So the problem is vscode client specific.

  5. Gourav2580 commented on Jan 25, 2026

    @Gourav2580

    /assign

  6. amritamishra01 commented on Mar 30, 2026

    @amritamishra01
    Contributor

    Hi, I’ve opened a PR with a client-side fix for the snippet escaping issue in resolved code action edits.

    It escapes literal \ and $ characters while preserving valid snippet placeholders.

    PR: #4378

  7. added this to the End March 2026 milestone on Mar 30, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Type

Projects

No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions