elastic/elasticsearch · error · MustacheException

Cannot expand '%s' because dynamic partial templates are not

Error message

Cannot expand '%s' because dynamic partial templates are not supported

What it means

Thrown by CustomMustacheVisitor.dynamicPartial() when a Mustache template uses the dynamic partial syntax ({{$name}} blocks with {{<name}} inclusion). Dynamic partials are a mustache extension for template inheritance/overriding that Elasticsearch's implementation does not support, for the same reason regular partials are unsupported: templates are inline strings with no file or classpath resolution.

Source

Thrown at modules/lang-mustache/src/main/java/org/elasticsearch/script/mustache/CustomMustacheFactory.java:152

            } else if (UrlEncoderCode.match(variable)) {
                list.add(new UrlEncoderCode(templateContext, df, mustache, variable));
            } else {
                list.add(new IterableCode(templateContext, df, mustache, variable));
            }
        }

        @Override
        public void partial(TemplateContext tc, String variable, String indent) {
            // throwing a mustache exception here is important because this gets caught, handled (closing readers, etc.),
            // and re-thrown in the mustache parser itself
            throw new MustacheException(Strings.format("Cannot expand '%s' because partial templates are not supported", variable));
        }

        @Override
        public void dynamicPartial(TemplateContext tc, final String variable, String indent) {
            // throwing a mustache exception here is important because this gets caught, handled (closing readers, etc.),
            // and re-thrown in the mustache parser itself
            throw new MustacheException(Strings.format("Cannot expand '%s' because dynamic partial templates are not supported", variable));
        }
    }

    /**
     * Base class for custom Mustache functions
     */
    private abstract static class CustomCode extends IterableCode {

        private final String code;

        CustomCode(TemplateContext tc, DefaultMustacheFactory df, Mustache mustache, String code) {
            super(tc, df, mustache, extractVariableName(code, mustache, tc));
            this.code = Objects.requireNonNull(code);
        }

        @Override
        public Writer execute(Writer writer, final List<Object> scopes) {
            Object resolved = get(scopes);

View on GitHub (pinned to db6a809a66)

Solutions

  1. Remove all {{$...}} and {{<...}} dynamic partial syntax from the template
  2. Use conditional sections ({{#var}}...{{/var}}) and parameters to achieve dynamic content variation
  3. Create separate stored templates for each variant and select the appropriate one client-side
  4. Use the {{#toJson}}var{{/toJson}} function for complex parameter-driven JSON injection

Example fix

// before — template with dynamic partial block:
{{$filter}}{"term": {"x": "{{val}}"}}{{/filter}}

// after — use a parameterized section instead:
{{#val}}{"term": {"x": "{{val}}"}}{{/val}}
Defensive patterns

Strategy: validation

Validate before calling

// Validate template source for dynamic partial syntax
String templateSource = "...";
if (templateSource.contains("{{$") || templateSource.contains("{{<")) {
    throw new IllegalArgumentException("Dynamic partial templates are not supported in Elasticsearch");
}

Prevention

When it happens

Trigger: Including dynamic partial syntax in a search template source. For example, {{$content}}...{{/content}} block definitions or {{<base}} template inheritance directives. The mustache parser invokes the visitor's dynamicPartial() method during compilation, which immediately throws.

Common situations: Using mustache template inheritance features from the mustache specification extensions. Porting templates from systems that use {{$block}} / {{<parent}} inheritance. Attempting to override sections of a base template dynamically.

Related errors


AI-assisted analysis of elastic/elasticsearch@db6a809a66 (2026-08-12). Data as JSON: /api/errors/868d30812642ed8a. Report an issue: GitHub.