{"record":{"id":"48a1557bdd2a7fd6","repo":"oracle/graal","slug":"can-t-store-into-varargsparameter-array","errorCode":null,"errorMessage":"Can't store into VarargsParameter array","messagePattern":"Can't store into VarargsParameter array","errorType":"exception","errorClass":"GraalError","httpStatus":null,"severity":"error","filePath":"compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/replacements/SnippetTemplate.java","lineNumber":1160,"sourceCode":"                    parameters[i] = params;\n\n                    VarargsPlaceholderNode placeholder = placeholders[i];\n                    if (placeholder != null) {\n                        for (Node usage : placeholder.usages().snapshot()) {\n                            if (usage instanceof LoadIndexedNode) {\n                                LoadIndexedNode loadIndexed = (LoadIndexedNode) usage;\n                                debug.dump(DebugContext.INFO_LEVEL, snippetCopy, \"Before replacing %s\", loadIndexed);\n                                LoadSnippetVarargParameterNode loadSnippetParameter = snippetCopy.add(\n                                                new LoadSnippetVarargParameterNode(params, loadIndexed.index(), loadIndexed.stamp(NodeView.DEFAULT)));\n                                snippetCopy.replaceFixedWithFixed(loadIndexed, loadSnippetParameter);\n                                debug.dump(DebugContext.INFO_LEVEL, snippetCopy, \"After replacing %s\", loadIndexed);\n                            } else if (usage instanceof StoreIndexedNode) {\n                                /*\n                                 * The template lowering doesn't really treat this as an array so\n                                 * you can't store back into the varargs. Allocate your own array if\n                                 * you really need this and EA should eliminate it.\n                                 */\n                                throw new GraalError(\"Can't store into VarargsParameter array\");\n                            }\n                        }\n                    }\n                } else {\n                    ParameterNode local = snippetCopy.getParameter(i);\n                    if (local == null) {\n                        // Parameter value was eliminated\n                        parameters[i] = UNUSED_PARAMETER;\n                    } else {\n                        parameters[i] = local;\n                    }\n                }\n            }\n\n            explodeLoops(snippetCopy, providers);\n\n            List<UnwindNode> unwindNodes = snippetCopy.getNodes(UnwindNode.TYPE).snapshot();\n            if (unwindNodes.size() == 0) {","sourceCodeStart":1142,"sourceCodeEnd":1178,"githubUrl":"https://github.com/oracle/graal/blob/a66e9ccd1d7bf2552883939aa0788dfd0e294aab/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/replacements/SnippetTemplate.java#L1142-L1178","documentation":"Snippet templates model a varargs snippet parameter with VarargsParameterNode, which is a placeholder, not a real array. Reads of its elements are rewritten to LoadSnippetVarargParameterNode, but a store back into the varargs array has no lowering, so SnippetTemplate throws GraalError during template instantiation when it sees a StoreIndexedNode on the varargs parameter.","triggerScenarios":"A @Snippet method declares an Object... varargs parameter and its body executes arr[i] = value (any store into the varargs parameter array).","commonSituations":"Writing a snippet that tries to normalize or mutate its varargs input in place; porting regular Java utility code into a snippet without adjusting for varargs handling.","solutions":["Copy the varargs into a locally allocated array before writing it; escape analysis removes the copy in generated code (as the source comment says).","Restructure the snippet to only read the varargs parameter and build a fresh result array."],"exampleFix":"// before (inside the @Snippet method)\nparams[0] = fallback; // GraalError: can't store into VarargsParameter array\n\n// after\nObject[] copy = Arrays.copyOf(params, params.length); // EA eliminates this allocation\ncopy[0] = fallback;","handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":["Treat snippet varargs parameters as read-only inputs; never assign into them.","If mutation is needed, copy first: Arrays.copyOf(params, params.length) — escape analysis removes the allocation.","Add a code-review checklist item for snippets: no stores to varargs parameters."],"tags":["graal","snippet","varargs","lowering","snippet-template"],"backgroundTag":null,"analyzedSha":"a66e9ccd1d7bf2552883939aa0788dfd0e294aab","analyzedAt":"2026-08-14T13:58:47.161Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}