quarkusio/quarkus · error · io.quarkus.qute.TemplateException

Duplicate global variable defined via @TemplateGlobal for th

Error message

Duplicate global variable defined via @TemplateGlobal for the name [%s]:
	- %s
	- %s

What it means

Thrown when two @TemplateGlobal elements produce a global variable with the same name. Qute registers globals in a name-keyed map and fails the build on collision so that template {name} resolution is unambiguous.

Source

Thrown at extensions/qute/deployment/src/main/java/io/quarkus/qute/deployment/QuteProcessor.java:3576

    }

    private void addGlobalField(AnnotationValue nameValue, FieldInfo field, Map<String, TemplateGlobalBuildItem> nameToGlobal) {
        TemplateGlobalGenerator.validate(field);
        String name = TemplateGlobal.ELEMENT_NAME;
        if (nameValue != null) {
            name = nameValue.asString();
        }
        if (name.equals(TemplateGlobal.ELEMENT_NAME)) {
            name = field.name();
        }
        TemplateGlobalBuildItem global = new TemplateGlobalBuildItem(name, field, field.type());
        addGlobalVariable(global, nameToGlobal);
    }

    private void addGlobalVariable(TemplateGlobalBuildItem global, Map<String, TemplateGlobalBuildItem> nameToGlobal) {
        TemplateGlobalBuildItem prev = nameToGlobal.put(global.getName(), global);
        if (prev != null) {
            throw new TemplateException(
                    String.format("Duplicate global variable defined via @TemplateGlobal for the name [%s]:\n\t- %s\n\t- %s",
                            global.getName(), global, prev));
        }
    }

    @BuildStep
    void collectTemplateDataAnnotations(BeanArchiveIndexBuildItem beanArchiveIndex,
            BuildProducer<TemplateDataBuildItem> templateDataAnnotations) {
        IndexView index = beanArchiveIndex.getIndex();
        Set<AnnotationInstance> annotationInstances = new HashSet<>();
        annotationInstances.addAll(index.getAnnotations(ValueResolverGenerator.TEMPLATE_DATA));
        for (AnnotationInstance containingInstance : index.getAnnotations(ValueResolverGenerator.TEMPLATE_DATA_CONTAINER)) {
            for (AnnotationInstance nestedInstance : containingInstance.value().asNestedArray()) {
                // We need to use the target of the containing instance
                annotationInstances.add(
                        AnnotationInstance.create(nestedInstance.name(), containingInstance.target(), nestedInstance.values()));
            }
        }

View on GitHub (pinned to e1c734241f)

Solutions

  1. Rename one of the colliding globals so each name is unique
  2. Remove the duplicate definition if redundant
  3. Consolidate both definitions into a single @TemplateGlobal class/field
  4. If the collision comes from a library, define your own uniquely-named global instead

Example fix

// before
@TemplateGlobal static String user() {...}  // in A
@TemplateGlobal static String user() {...}  // in B

// after
@TemplateGlobal static String user() {...}      // in A
@TemplateGlobal static String currentUser() {...} // renamed in B
Defensive patterns

Strategy: validation

Validate before calling

// Ensure global names are unique across all @TemplateGlobal classes
Set<String> seen = new HashSet<>();
for (String name : allGlobalNames) {
    if (!seen.add(name)) { throw new IllegalStateException("Duplicate global: " + name); }
}

Prevention

When it happens

Trigger: Two fields or static methods annotated with @TemplateGlobal producing the same variable name; a @TemplateGlobal class with auto-generated members whose name collides with another explicit global; two dependencies both defining a global with the same key.

Common situations: Common names like 'user', 'now', or 'version' defined in multiple global classes; merging branches that each added a global with the same name; copy-pasting a global method and not renaming it.

Related errors


AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05). Data as JSON: /api/errors/7de05b52a07aaa07. Report an issue: GitHub.