OpenFeign/feign · error · RuntimeException

Unable to enrich field

Error message

Unable to enrich field ${field}

What it means

Thrown by BaseBuilder.enrich when applying Capabilities to a builder field fails via reflection: field.set(clone, enriched) throws IllegalArgumentException (value not assignable to the field type) or IllegalAccessException. This wraps the reflective enrichment of builder components (clients, encoders, decoders, interceptors) with a Capability-enriched replacement.

Solutions

  1. Fix the Capability so enrich returns an instance assignable to the component's interface type (Client, Encoder, Decoder, etc.)
  2. Log/inspect the cause IllegalArgumentException message which names the offending field and expected type
  3. Disable the suspect Capability and re-enable components one by one to find which one returns the wrong type

Example fix

// before
class BadCapability implements Capability {
  @Override
  public Encoder enrich(Encoder encoder) { return null; } // null/wrong type
}
// after
class GoodCapability implements Capability {
  @Override
  public Encoder enrich(Encoder encoder) {
    return new MyEncoderWrapper(encoder); // must implement feign Encoder
  }
}
Defensive patterns

Strategy: validation

Validate before calling

Object out = capability.enrich(original);
if (out != null && !fieldType.isInstance(out)) {
  throw new IllegalStateException(fieldType.getName() + " required, got " + out.getClass());
}

Type guard

boolean validEnrichment(Object out, Class<?> fieldType) {
  return out == null || fieldType.isInstance(out);
}

Try / catch

try { Feign.builder().addCapability(cap).build(); }
catch (RuntimeException e) { if (e.getMessage().startsWith("Unable to enrich field")) { /* wrong-type Capability */ } }

Prevention

When it happens

Trigger: A Capability.enrich returns an object whose type does not implement the field's declared interface type (e.g. a Capability returning a wrong-typed wrapper); or a builder field is not accessible in this environment.

Common situations: Custom Capability whose enrich override returns an incompatible instance due to generics erasure or a wrong cast; upgrading Feign and a Capability targeting a field type that changed.

Understand the failure class

Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.

Related errors


AI-assisted analysis of OpenFeign/feign@e2a1e27560 (2026-09-10). Data as JSON: /api/errors/fdd00c6e4862d8fe. Report an issue: GitHub.

Appendix: source

Thrown at core/src/main/java/feign/BaseBuilder.java:364

                  final Object originalValue = field.get(clone);
                  final Object enriched;
                  if (originalValue instanceof List) {
                    Type ownerType =
                        ((ParameterizedType) field.getGenericType()).getActualTypeArguments()[0];
                    enriched =
                        ((List) originalValue)
                            .stream()
                                .map(
                                    value ->
                                        Capability.enrich(
                                            value, (Class<?>) ownerType, capabilities))
                                .collect(Collectors.toList());
                  } else {
                    enriched = Capability.enrich(originalValue, field.getType(), capabilities);
                  }
                  field.set(clone, enriched);
                } catch (IllegalArgumentException | IllegalAccessException e) {
                  throw new RuntimeException("Unable to enrich field " + field, e);
                } finally {
                  field.setAccessible(false);
                }
              });

      // enrich each request interceptor, then enrich the list as a whole
      RequestInterceptor[] requestArray =
          clone.requestInterceptors.toArray(new RequestInterceptor[0]);
      for (int i = 0; i < requestArray.length; i++) {
        requestArray[i] =
            (RequestInterceptor)
                Capability.enrich(requestArray[i], RequestInterceptor.class, capabilities);
      }
      RequestInterceptors requestInterceptors =
          (RequestInterceptors)
              Capability.enrich(
                  new RequestInterceptors(Arrays.asList(requestArray)),
                  RequestInterceptors.class,

View on GitHub (pinned to e2a1e27560)