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
- Remove all {{$...}} and {{<...}} dynamic partial syntax from the template
- Use conditional sections ({{#var}}...{{/var}}) and parameters to achieve dynamic content variation
- Create separate stored templates for each variant and select the appropriate one client-side
- 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
- Never use {{$block}} or {{<parent}} syntax in Elasticsearch templates
- Use parameterized sections {{#var}}...{{/var}} for dynamic content
- Avoid template inheritance patterns from other mustache implementations
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
- Cannot expand '%s' because partial templates are not support
- Unable to encode value
- No encoder found for media type [{}]
- Mustache function [{}] must contain one and only one identif
- Failed to convert object to JSON
AI-assisted analysis of elastic/elasticsearch@db6a809a66 (2026-08-12).
Data as JSON: /api/errors/868d30812642ed8a.
Report an issue: GitHub.