{"record":{"id":"335ed46f4d901224","repo":"quarkusio/quarkus","slug":"expected-a-value-of-type-type-getname-for-opt","errorCode":null,"errorMessage":"Expected a value of type ${type.getName()} for option ${name} but got ${o} of type ${o.getClass().getName()}","messagePattern":"Expected a value of type (.+?) for option (.+?) but got (.+?) of type (.+?)","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"independent-projects/tools/registry-client/src/main/java/io/quarkus/registry/RegistryExtensionResolver.java","lineNumber":56,"sourceCode":"     * Returns an extra config option value with an expected type.\n     * If an option was not configured, the returned value will be null.\n     * If the configured value cannot be cast to an expected type, the method will throw an error.\n     *\n     * @param config registry configuration\n     * @param name option name\n     * @param type expected value type\n     * @return configured value or null\n     * @param <T> expected value type\n     */\n    private static <T> T getExtraConfigOption(RegistryConfig config, String name, Class<T> type) {\n        Object o = config.getExtra().get(name);\n        if (o == null) {\n            return null;\n        }\n        if (type.isInstance(o)) {\n            return (T) o;\n        }\n        throw new IllegalArgumentException(\n                \"Expected a value of type \" + type.getName() + \" for option \" + name + \" but got \" + o\n                        + \" of type \" + o.getClass().getName());\n    }\n\n    /**\n     * Returns offering configured by the user in the registry configuration or null, in case\n     * no offering was configured.\n     *\n     * An offering would be the name part of the {@code <name>-support} in the extension metadata.\n     *\n     * @param config registry configuration\n     * @return user configured offering or null\n     */\n    private static String getConfiguredOfferingOrNull(RegistryConfig config) {\n        var offering = getExtraConfigOption(config, OFFERING, String.class);\n        return offering == null || offering.isBlank() ? null : offering;\n    }\n","sourceCodeStart":38,"sourceCodeEnd":74,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/independent-projects/tools/registry-client/src/main/java/io/quarkus/registry/RegistryExtensionResolver.java#L38-L74","documentation":"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.","triggerScenarios":"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().","commonSituations":"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.","solutions":["Quote the value in the config file so it parses as the expected type (e.g. offering: \"my-offering\").","Inspect the actual type named in the message and convert the configured value to that type.","When building RegistryConfig programmatically, put correctly-typed values into extra (String for offering, String stream IDs for recommend-streams-starting).","Wrap the resolver construction in a try-catch and validate the extra map types before use."],"exampleFix":"// before (.quarkus/config.yaml)\nextra:\n  offering: 12345      # parsed as Integer -> IllegalArgumentException\n// after\nextra:\n  offering: \"12345\"    # quoted, parsed as String","handlingStrategy":"validation","validationCode":"// Java\nObject offering = registryConfig.getExtra().get(\"offering\");\nif (offering != null && !(offering instanceof String)) {\n    throw new IllegalArgumentException(\"offering must be a quoted string, got: \" + offering.getClass());\n}","typeGuard":"// Java\nstatic <T> T asTypeOrNull(Map<String, Object> extra, String name, Class<T> type) {\n    Object o = extra.get(name);\n    return type.isInstance(o) ? type.cast(o) : null; // avoids the throw\n}","tryCatchPattern":"// Java\ntry {\n    resolver = ExtensionCatalogResolver.builder().setConfig(config).build();\n} catch (IllegalArgumentException e) {\n    if (e.getMessage().contains(\"Expected a value of type\")) {\n        logger.error(\"Fix registry config extra types: \" + e.getMessage());\n    }\n    throw e;\n}","preventionTips":["Always quote string-ish values in .quarkus/config.yaml (offering: \"value\").","Remember YAML parsers turn unquoted 123 into Integer and true into Boolean.","When constructing RegistryConfig in code, use the exact expected Java types.","Add a startup config sanity-check that validates extra option types."],"tags":["configuration","type-mismatch","yaml"],"backgroundTag":"config-option-type-mismatch","analyzedSha":"e1c734241f34c7919086ceb4c9262b4a58f6de44","analyzedAt":"2026-09-05T17:01:29.979Z","contentChangedAt":"2026-09-05T17:01:29.979Z","schemaVersion":2},"datasetVersion":"2026-09-12T22:17:10.623Z"}