{"record":{"id":"1c04864ed66071db","repo":"elastic/elasticsearch","slug":"parameter-name-is-missing","errorCode":null,"errorMessage":"Parameter [{name}] is missing","messagePattern":"Parameter \\[(.+?)\\] is missing","errorType":"validation","errorClass":"MustacheInvalidParameterException","httpStatus":null,"severity":"error","filePath":"modules/lang-mustache/src/main/java/org/elasticsearch/script/mustache/CustomReflectionObjectHandler.java","lineNumber":92,"sourceCode":"         * that is, with the permissions we're running with, it would always return null ('not found!') or throw\n         * an exception ('found, but you cannot do this!') -- so by overriding to null we're effectively saying\n         * \"you will never find success going down this path, so don't bother trying\"\n         */\n        return null;\n    }\n\n    private static final class DetectMissingParamsGuardedBinding extends GuardedBinding {\n        private final Code code;\n\n        DetectMissingParamsGuardedBinding(ObjectHandler oh, String name, TemplateContext tc, Code code) {\n            super(oh, name, tc, code);\n            this.code = code;\n        }\n\n        protected synchronized Wrapper getWrapper(String name, List<Object> scopes) {\n            Wrapper wrapper = super.getWrapper(name, scopes);\n            if (wrapper instanceof MissingWrapper && code instanceof ValueCode) {\n                throw new MustacheInvalidParameterException(\"Parameter [\" + name + \"] is missing\");\n            }\n            return wrapper;\n        }\n    }\n\n    private static final class ArrayMap extends AbstractMap<Object, Object> implements Iterable<Object> {\n\n        private final Object array;\n        private final int length;\n\n        ArrayMap(Object array) {\n            this.array = array;\n            this.length = Array.getLength(array);\n        }\n\n        @Override\n        public Object get(Object key) {\n            if (\"size\".equals(key)) {","sourceCodeStart":74,"sourceCodeEnd":110,"githubUrl":"https://github.com/elastic/elasticsearch/blob/db6a809a667c081ca1dc7500389d26975573215f/modules/lang-mustache/src/main/java/org/elasticsearch/script/mustache/CustomReflectionObjectHandler.java#L74-L110","documentation":"Thrown by DetectMissingParamsGuardedBinding when detect_missing_params is enabled and a template references a parameter ({{paramName}}) that was not provided in the params object. This is an opt-in strict mode: when the Script option 'detect_missing_params' is set to 'true', the CustomReflectionObjectHandler uses a GuardedBinding that checks each variable binding and throws MustacheInvalidParameterException if the wrapper is a MissingWrapper for a ValueCode (a plain variable reference).","triggerScenarios":"Executing a search template with {\"detect_missing_params\": true} in the script options, where the template references {{field_name}} but no matching key exists in the params object. For example, template source contains {{category}} but params is {\"categories\": \"books\"} (typo or missing key).","commonSituations":"Typos in parameter names between template and params. Forgetting to pass a required parameter. Dynamically generated templates where some branches reference params not always supplied. Enabling detect_missing_params for stricter validation during development but forgetting to update params when adding new template variables.","solutions":["Provide all parameters referenced in the template in the params object — check for typos in the parameter name from the error message","If the parameter is optional, use a conditional section {{#param}}...{{/param}} instead of a bare {{param}} reference","Disable detect_missing_params if you want missing parameters to render as empty (set to false or omit the option)","Audit the template source for all {{variable}} references and cross-check against the params keys"],"exampleFix":"// before — missing parameter with detect_missing_params:\nPOST /_search/template\n{\n  \"source\": { \"query\": { \"term\": { \"category\": \"{{category}}\" } } },\n  \"params\": { \"cat\": \"books\" },\n  \"detect_missing_params\": true\n}\n\n// after — match the parameter name:\nPOST /_search/template\n{\n  \"source\": { \"query\": { \"term\": { \"category\": \"{{category}}\" } } },\n  \"params\": { \"category\": \"books\" },\n  \"detect_missing_params\": true\n}","handlingStrategy":"validation","validationCode":"// Validate all template variables are present in params before execution\nSet<String> extractTemplateVars(String templateSource) {\n    // extract all {{varName}} references (not sections)\n    Set<String> vars = new HashSet<>();\n    Pattern p = Pattern.compile(\"\\\\{\\{(?![#/^/>&])([^}]+)\\}\\}\");\n    Matcher m = p.matcher(templateSource);\n    while (m.find()) vars.add(m.group(1).trim());\n    return vars;\n}\n// before execution: assert params.keySet().containsAll(extractTemplateVars(source))","typeGuard":null,"tryCatchPattern":"// When detect_missing_params is enabled, catch MustacheInvalidParameterException\ntry {\n    template.execute(writer, params);\n} catch (MustacheInvalidParameterException e) {\n    // parameter is missing — provide a default or fix the params\n    log.warn(\"Missing template parameter: {}\", e.getMessage());\n}","preventionTips":["Cross-check all {{variable}} references against params keys before execution","Use {{#param}}...{{/param}} conditional sections for optional parameters","Enable detect_missing_params in development to catch typos early","Keep a registry of required parameters for each stored template"],"tags":["elasticsearch","lang-mustache","missing-params","validation","template"],"analyzedSha":"db6a809a667c081ca1dc7500389d26975573215f","analyzedAt":"2026-08-12T01:39:14.192Z","schemaVersion":2},"datasetVersion":"2026-08-12T06:17:24.410Z"}