{"record":{"id":"879001feecd282b3","repo":"quarkusio/quarkus","slug":"not-a-hint-info","errorCode":null,"errorMessage":"Not a hint info","messagePattern":"Not a hint info","errorType":"exception","errorClass":"java.lang.IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"extensions/qute/deployment/src/main/java/io/quarkus/qute/deployment/TypeInfos.java","lineNumber":277,"sourceCode":"\n        boolean hasHints() {\n            return false;\n        }\n\n        VirtualMethodInfo asVirtualMethod() {\n            throw new IllegalArgumentException(\"Not a virtual method\");\n        }\n\n        PropertyInfo asProperty() {\n            throw new IllegalArgumentException(\"Not a property\");\n        }\n\n        TypeInfo asTypeInfo() {\n            throw new IllegalArgumentException(\"Not a type info: \" + getClass().getName() + \":\" + toString());\n        }\n\n        HintInfo asHintInfo() {\n            throw new IllegalArgumentException(\"Not a hint info\");\n        }\n\n        @Override\n        public String toString() {\n            return value;\n        }\n\n    }\n\n    static abstract class HintInfo extends Info {\n\n        static final Pattern HINT_PATTERN = Pattern.compile(\"\\\\<[a-zA-Z_0-9#-]+\\\\>\");\n\n        // <loop#1>, <set#10><loop-element>, etc.\n        final List<String> hints;\n\n        HintInfo(String value, Expression.Part part, String hintStr) {\n            super(value, part);","sourceCodeStart":259,"sourceCodeEnd":295,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/extensions/qute/deployment/src/main/java/io/quarkus/qute/deployment/TypeInfos.java#L259-L295","documentation":"TypeInfo is a sealed hierarchy of parsed template expression fragments; only HintInfo subclasses implement asHintInfo(). The base TypeInfo.asHintInfo() unconditionally throws IllegalArgumentException('Not a hint info') when called on a non-hint node (e.g. a plain part, method, or bracket), acting as a safe downcast guard.","triggerScenarios":"Internal validation code (validateCheckedFragments, validateNestedExpressions, processRoot, processHintsIfNeeded) or third-party extension code walks type info fragments and calls asHintInfo() on a fragment that is not a hint.","commonSituations":"Custom Qute/extension code iterating expression parts and assuming every fragment is a hint; template expressions that end in a non-hint segment causing the traversal to hit the wrong node type.","solutions":["Call asTypeInfo() or instanceof-check HintInfo before calling asHintInfo()","Inspect the expression in the template: the code expected a hint (loop/when section value hint) but found another fragment","If it comes from a custom extension, fix the fragment-type dispatch logic"],"exampleFix":"// before\ninfo.asHintInfo();\n// after\nif (info instanceof HintInfo) { info.asHintInfo(); } else { info.asTypeInfo(); }","handlingStrategy":"type-guard","validationCode":"boolean isHint = info instanceof HintInfo;","typeGuard":"if (info instanceof HintInfo hint) {\n    // safe to use hint-specific API\n} else {\n    TypeInfo type = info.asTypeInfo();\n}","tryCatchPattern":null,"preventionTips":["Check the concrete fragment type before calling asHintInfo()/asTypeInfo()","Read the sealed TypeInfo hierarchy docs to know which nodes are hints","Test expression validation against templates whose expressions end in non-hint segments"],"tags":["qute","internal","type-hierarchy","programming-error"],"backgroundTag":"invalid-downcast","analyzedSha":"e1c734241f34c7919086ceb4c9262b4a58f6de44","analyzedAt":"2026-09-05T17:01:29.979Z","contentChangedAt":"2026-09-05T17:01:29.979Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}