{"record":{"id":"68c28222d922b9eb","repo":"projectlombok/lombok","slug":"expected-a-single-value-but-method-getname-h","errorCode":null,"errorMessage":"Expected a single value, but ${method.getName()} has an array of values","messagePattern":"Expected a single value, but (.+?) has an array of values","errorType":"exception","errorClass":"AnnotationValueDecodeFail","httpStatus":null,"severity":"error","filePath":"src/core/lombok/core/AnnotationValues.java","lineNumber":251,"sourceCode":"\t\t\tpublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {\n\t\t\t\tAnnotationValue v = values.get(method.getName());\n\t\t\t\tif (v == null) {\n\t\t\t\t\tObject defaultValue = method.getDefaultValue();\n\t\t\t\t\tif (defaultValue != null) return defaultValue;\n\t\t\t\t\tthrow makeNoDefaultFail(v, method);\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\tboolean isArray = false;\n\t\t\t\tClass<?> expected = method.getReturnType();\n\t\t\t\tObject array = null;\n\t\t\t\tif (expected.isArray()) {\n\t\t\t\t\tisArray = true;\n\t\t\t\t\texpected = expected.getComponentType();\n\t\t\t\t\tarray = Array.newInstance(expected, v.valueGuesses.size());\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\tif (!isArray && v.valueGuesses.size() > 1) {\n\t\t\t\t\tthrow new AnnotationValueDecodeFail(v, \n\t\t\t\t\t\t\"Expected a single value, but \" + method.getName() + \" has an array of values\", -1);\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\tif (v.valueGuesses.size() == 0 && !isArray) {\n\t\t\t\t\tObject defaultValue = method.getDefaultValue();\n\t\t\t\t\tif (defaultValue == null) throw makeNoDefaultFail(v, method);\n\t\t\t\t\treturn defaultValue;\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\tint idx = 0;\n\t\t\t\tfor (Object guess : v.valueGuesses) {\n\t\t\t\t\tObject result = guess == null ? null : guessToType(guess, expected, v, idx);\n\t\t\t\t\tif (!isArray) {\n\t\t\t\t\t\tif (result == null) {\n\t\t\t\t\t\t\tObject defaultValue = method.getDefaultValue();\n\t\t\t\t\t\t\tif (defaultValue == null) throw makeNoDefaultFail(v, method);\n\t\t\t\t\t\t\treturn defaultValue;\n\t\t\t\t\t\t}","sourceCodeStart":233,"sourceCodeEnd":269,"githubUrl":"https://github.com/projectlombok/lombok/blob/6d6a3e9fec0a9555702561fbeb8eac836575116e/src/core/lombok/core/AnnotationValues.java#L233-L269","documentation":"AnnotationValues.invoke() reflectsively invokes an annotation method and builds the return value. If the method's return type is NOT an array but the annotation source supplied more than one value guess, lombok throws AnnotationValueDecodeFail: the annotation declared a scalar member but was given array syntax values. This guards the contract between the annotation declaration and how it was used in source.","triggerScenarios":"Calling invoke()/getValue on an AnnotationValues instance where method.getName() has a non-array return type but v.valueGuesses.size() > 1 — i.e. source used value={a,b} (or repeated elements) for a member declared as a scalar (e.g. String value() not String[] value()).","commonSituations":"Copy-pasting annotation usage where the member was changed from an array type to a scalar (or vice versa) after a library version change; hand-written annotation trees built by AST transformers supplying multiple guesses for a scalar member.","solutions":["Make the annotation usage match the declaration: pass a single value for a scalar member (value = \"x\" instead of value = {\"x\",\"y\"}).","Or change the annotation member declaration to an array type (e.g. String[] value()) if multiple values are intended.","If you are an annotation handler author, check isArray/expected.getComponentType() before expecting multiple guesses.","Check library upgrade notes — annotation member types sometimes change between versions."],"exampleFix":"// before (value() declared as String)\n@MyAnn(value = {\"a\", \"b\"})\n// after\n@MyAnn(value = \"a\") // or declare String[] value() in the annotation","handlingStrategy":"validation","validationCode":"Class<?> rt = method.getReturnType(); int n = annotationValues.getRawExpressions(method.getName()).size(); if (!rt.isArray() && n > 1) throw new IllegalStateException(\"Scalar member got \" + n + \" values\");","typeGuard":"function isScalarUsage(memberType, guessCount) { return memberType !== 'array' && guessCount <= 1; }","tryCatchPattern":"try { T v = annotationValues.invoke(method); } catch (AnnotationValueDecodeFail e) { log.error(\"Value/count mismatch for \" + method.getName()); }","preventionTips":["Match annotation usage syntax to the member's declared type (scalar vs array).","When libraries change member types across versions, update all annotation call sites.","Unit-test annotation handlers against both single and array forms."],"tags":["annotations","lombok","type-mismatch","reflection"],"backgroundTag":"type-mismatch","analyzedSha":"6d6a3e9fec0a9555702561fbeb8eac836575116e","analyzedAt":"2026-09-07T23:18:01.841Z","contentChangedAt":"2026-09-07T23:18:01.841Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}