apache/skywalking · error · IllegalArgumentException

Cannot resolve getter {simpleName}.{getterName}() for type {

Error message

Cannot resolve getter {simpleName}.{getterName}() for type {typeName}. Check the field path in the LAL rule.

What it means

Thrown at LAL compile time during reflection-based resolution of a parsed.* chain on a typed input (parser type NONE with an inputType). The codegen builds a getter name via get + Capitalized(field) and calls Class.getMethod on each hop; when the typed class has no such getter, compilation aborts with the class, getter and declared input type in the message. This is the typed-input counterpart of the unknown log field error.

Source

Thrown at oap-server/analyzer/log-analyzer/src/main/java/org/apache/skywalking/oap/log/analyzer/v2/compiler/LALValueCodegen.java:1121

        }

        final String typeName = rootType.getName();
        final StringBuilder chainKey = new StringBuilder();
        String prevVar = rootExpr;
        Class<?> currentType = rootType;
        boolean prevCanBeNull = rootCanBeNull;

        for (int i = 0; i < fieldSegments.size(); i++) {
            final LALScriptModel.FieldSegment seg = fieldSegments.get(i);
            final String field = seg.getName();
            final String getterName = "get" + Character.toUpperCase(field.charAt(0))
                + field.substring(1);

            final Method getter;
            try {
                getter = currentType.getMethod(getterName);
            } catch (NoSuchMethodException e) {
                throw new IllegalArgumentException(
                    "Cannot resolve getter " + currentType.getSimpleName()
                        + "." + getterName + "() for type "
                        + typeName + ". Check the field path in the LAL rule.");
            }
            final Class<?> returnType = getter.getReturnType();

            if (chainKey.length() > 0) {
                chainKey.append(".");
            }
            chainKey.append(field);
            final String key = chainKey.toString();
            final boolean isLast = i == fieldSegments.size() - 1;

            // Primitive final segment: return inline expression, no variable
            if (isLast && returnType.isPrimitive()) {
                final String rawAccess = prevVar + "." + getterName + "()";
                genCtx.lastResolvedType = returnType;
                genCtx.lastRawChain = rawAccess;

View on GitHub (pinned to 102af09b4a)

Solutions

  1. Match each path segment to an actual getX() getter on the input class — check the generated protobuf getters for the exact field hierarchy
  2. Add the missing intermediate segments so every hop resolves, e.g. parsed.response.code instead of parsed.responseCode
  3. Verify the inputType is what you think (YAML inputType: or the layer's LALSourceTypeProvider default) — the message names the type reflection walked
  4. If the field genuinely has no getter, expose it (implement ToJson on the input type) or parse it as JSON instead of typed access

Example fix

# before (inputType HTTPAccessLogEntry)
status parsed.responseCode as Integer

# after
status parsed.response.code as Integer
Defensive patterns

Strategy: type-guard

Validate before calling

// Pre-deploy check for typed inputs: verify each parsed.* path resolves
Class<?> t = Class.forName(ruleInputType);
for (String[] path : parsedPathsFromRule) {
    Class<?> cur = t;
    for (String seg : path) {
        java.lang.reflect.Method m = cur.getMethod("get" + Character.toUpperCase(seg.charAt(0)) + seg.substring(1));
        cur = m.getReturnType();
    }
}

Type guard

boolean pathResolves(Class<?> inputType, String... fields) {
    Class<?> cur = inputType;
    for (String f : fields) {
        String getter = "get" + Character.toUpperCase(f.charAt(0)) + f.substring(1);
        try { cur = cur.getMethod(getter).getReturnType(); }
        catch (NoSuchMethodException e) { return false; }
    }
    return true;
}

Prevention

When it happens

Trigger: parsed.responseCode on a type that exposes getResponse().getCode(); navigating one level too shallow/too deep for the proto or POJO; field names with different casing than the getter (field x → getX()); using an inputType whose fields changed between versions.

Common situations: Protobuf typed inputs (e.g. Envoy HTTPAccessLogEntry) where the LAL path must match the proto field hierarchy exactly; upgrading a proto dependency that renamed fields; writing parsed.latency when the proto nests it as parsed.common_properties.latency.

Related errors


AI-assisted analysis of apache/skywalking@102af09b4a (2026-08-14). Data as JSON: /api/errors/8e826717f634e350. Report an issue: GitHub.