{"record":{"id":"cb39c04aad9c1608","repo":"apache/maven","slug":"failed-to-interpolate-field-field-on-clas","errorCode":null,"errorMessage":"Failed to interpolate field: \" + field + \" on class: \" + cls.getName()","messagePattern":"Failed to interpolate field: \" \\+ field \\+ \" on class: \" \\+ cls\\.getName\\(\\)","errorType":"exception","errorClass":"ModelInterpolationException","httpStatus":null,"severity":"error","filePath":"compat/maven-compat/src/main/java/org/apache/maven/project/interpolation/StringSearchModelInterpolator.java","lineNumber":252,"sourceCode":"                                                    } else {\n                                                        interpolationTargets.add(value);\n                                                    }\n                                                }\n                                            }\n                                        }\n                                    }\n                                } else {\n                                    Object value = field.get(target);\n                                    if (value != null) {\n                                        if (field.getType().isArray()) {\n                                            evaluateArray(value);\n                                        } else {\n                                            interpolationTargets.add(value);\n                                        }\n                                    }\n                                }\n                            } catch (IllegalArgumentException | IllegalAccessException e) {\n                                throw new ModelInterpolationException(\n                                        \"Failed to interpolate field: \" + field + \" on class: \" + cls.getName(), e);\n                            }\n                        } finally {\n                            field.setAccessible(isAccessible);\n                        }\n                    }\n                }\n\n                traverseObjectWithParents(cls.getSuperclass(), target);\n            }\n        }\n\n        private boolean isQualifiedForInterpolation(Class<?> cls) {\n            return !cls.getPackage().getName().startsWith(\"java\")\n                    && !cls.getPackage().getName().startsWith(\"sun.nio.fs\")\n                    // org.apache.maven.api.model.InputLocation can be self-referencing\n                    && !cls.getName().equals(\"org.apache.maven.api.model.InputLocation\");\n        }","sourceCodeStart":234,"sourceCodeEnd":270,"githubUrl":"https://github.com/apache/maven/blob/e4093d4e120eac99d6bdce5ba67cace2f3085c97/compat/maven-compat/src/main/java/org/apache/maven/project/interpolation/StringSearchModelInterpolator.java#L234-L270","documentation":"Thrown by StringSearchModelInterpolator while reflectively traversing model fields: field.get(target) threw IllegalArgumentException or IllegalAccessException. This interpolator walks the object graph (including arrays and superclass fields) to interpolate strings in place; the exception names the exact field and class where reflection failed. Causes include a mutated/incompatible field type (the field was changed between the accessibility check and the read) or access being denied after setAccessible in a hardened JVM.","triggerScenarios":"traverseObjectWithParents() calls Field.get on a model class when (a) the object held in the field's value is not an instance of the field's declared type (IllegalArgumentException, usually concurrent model mutation by another thread/plugin), or (b) setAccessible(false)-style denial by a SecurityManager/JPMS strong encapsulation (IllegalAccessException).","commonSituations":"Parallel builds where one plugin mutates the model while interpolation runs; custom model classes with covariance tricks; running Maven on JDKs with module access restrictions hitting legacy reflection; corrupted plugin-provided model instances.","solutions":["Check the named field/class: it pinpoints exactly which model part failed; reproduce with a single-threaded build (-T1) to rule out concurrent model mutation","Remove/upgrade plugins that swap model field values in background threads","Prefer the standard project builder path (field interpolation) over manually invoking StringSearchModelInterpolator on shared models","On restrictive JDKs, ensure legacy reflection is permitted (no deny-ish --add-opens removal) or use a Maven version compatible with that JDK","Clone the model before interpolating when embedding, so no other code mutates it mid-traversal"],"exampleFix":"// before: interpolating a shared model while another thread mutates it\ninterpolator.interpolate(sharedModel, ...);\n// after: interpolate a private copy\nModel copy = sharedModel.clone();\ninterpolator.interpolate(copy, ...);","handlingStrategy":"try-catch","validationCode":"// When embedding: interpolate a clone so concurrent mutation cannot break reflection\nModel snapshot = model.clone();","typeGuard":null,"tryCatchPattern":"try {\n    interpolator.interpolate(model, ...);\n} catch (ModelInterpolationException e) {\n    if (e.getMessage().startsWith(\"Failed to interpolate field\")) {\n        // named field/class pinpoints the mutation; retry single-threaded on a clone\n    }\n}","preventionTips":["Do not share Model instances across threads during interpolation","Clone models before manual interpolation in embedded usage","Run -T1 when this appears intermittently to confirm a concurrency cause"],"tags":["maven","interpolation","reflection","concurrency","model"],"backgroundTag":"reflection-field-access-failed","analyzedSha":"e4093d4e120eac99d6bdce5ba67cace2f3085c97","analyzedAt":"2026-08-21T22:58:24.034Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}