quarkusio/quarkus · error · IllegalArgumentException

Expected a value of type

Error message

Expected a value of type ${type.getName()} for option ${name} but got ${o} of type ${o.getClass().getName()}

What it means

RegistryExtensionResolver.getExtraConfigOption() reads a free-form value from the registry config 'extra' map and casts it to the expected type. If the configured value's runtime type differs from the expected Class (e.g. an Integer where a String is expected), an IllegalArgumentException is thrown naming the option, expected type, value, and actual type.

Solutions

  1. Quote the value in the config file so it parses as the expected type (e.g. offering: "my-offering").
  2. Inspect the actual type named in the message and convert the configured value to that type.
  3. When building RegistryConfig programmatically, put correctly-typed values into extra (String for offering, String stream IDs for recommend-streams-starting).
  4. Wrap the resolver construction in a try-catch and validate the extra map types before use.

Example fix

// before (.quarkus/config.yaml)
extra:
  offering: 12345      # parsed as Integer -> IllegalArgumentException
// after
extra:
  offering: "12345"    # quoted, parsed as String
Defensive patterns

Strategy: validation

Validate before calling

// Java
Object offering = registryConfig.getExtra().get("offering");
if (offering != null && !(offering instanceof String)) {
    throw new IllegalArgumentException("offering must be a quoted string, got: " + offering.getClass());
}

Type guard

// Java
static <T> T asTypeOrNull(Map<String, Object> extra, String name, Class<T> type) {
    Object o = extra.get(name);
    return type.isInstance(o) ? type.cast(o) : null; // avoids the throw
}

Try / catch

// Java
try {
    resolver = ExtensionCatalogResolver.builder().setConfig(config).build();
} catch (IllegalArgumentException e) {
    if (e.getMessage().contains("Expected a value of type")) {
        logger.error("Fix registry config extra types: " + e.getMessage());
    }
    throw e;
}

Prevention

When it happens

Trigger: RegistryConfig.extra containing option 'offering' (expected String) or 'recommend-streams-starting' boundaries (expected String values) typed as a number/boolean/Map because of YAML/JSON type inference, accessed via getConfiguredOfferingOrNull() or recommendStreamsStarting().

Common situations: In YAML, writing offering: 123 (parsed as Integer) instead of offering: "123"; quoting mistakes or programmatic RegistryConfig construction with wrong Java types in the extra map.

Related errors


AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05). Data as JSON: /api/errors/335ed46f4d901224. Report an issue: GitHub.

Appendix: source

Thrown at independent-projects/tools/registry-client/src/main/java/io/quarkus/registry/RegistryExtensionResolver.java:56

     * Returns an extra config option value with an expected type.
     * If an option was not configured, the returned value will be null.
     * If the configured value cannot be cast to an expected type, the method will throw an error.
     *
     * @param config registry configuration
     * @param name option name
     * @param type expected value type
     * @return configured value or null
     * @param <T> expected value type
     */
    private static <T> T getExtraConfigOption(RegistryConfig config, String name, Class<T> type) {
        Object o = config.getExtra().get(name);
        if (o == null) {
            return null;
        }
        if (type.isInstance(o)) {
            return (T) o;
        }
        throw new IllegalArgumentException(
                "Expected a value of type " + type.getName() + " for option " + name + " but got " + o
                        + " of type " + o.getClass().getName());
    }

    /**
     * Returns offering configured by the user in the registry configuration or null, in case
     * no offering was configured.
     *
     * An offering would be the name part of the {@code <name>-support} in the extension metadata.
     *
     * @param config registry configuration
     * @return user configured offering or null
     */
    private static String getConfiguredOfferingOrNull(RegistryConfig config) {
        var offering = getExtraConfigOption(config, OFFERING, String.class);
        return offering == null || offering.isBlank() ? null : offering;
    }

View on GitHub (pinned to e1c734241f)