{"id":"b68498eca95479ed","repo":"junit-team/junit5","slug":"failed-to-transform-configuration-parameter-with-k","errorCode":null,"errorMessage":"Failed to transform configuration parameter with key '%s' and initial value '%s'","messagePattern":"Failed to transform configuration parameter with key '(.+?)' and initial value '(.+?)'","errorType":"exception","errorClass":"JUnitException","httpStatus":null,"severity":"error","filePath":"junit-platform-engine/src/main/java/org/junit/platform/engine/ConfigurationParameters.java","lineNumber":129,"sourceCode":"\t * @return an {@code Optional} containing the value; never {@code null}\n\t * but potentially empty\n\t *\n\t * @since 1.3\n\t * @see #getBoolean(String)\n\t * @see System#getProperty(String)\n\t * @see #CONFIG_FILE_NAME\n\t */\n\t@API(status = STABLE, since = \"1.3\")\n\tdefault <T> Optional<T> get(String key, Function<? super String, ? extends @Nullable T> transformer) {\n\t\tPreconditions.notNull(transformer, \"transformer must not be null\");\n\t\treturn get(key).map(input -> {\n\t\t\ttry {\n\t\t\t\treturn transformer.apply(input);\n\t\t\t}\n\t\t\tcatch (Exception ex) {\n\t\t\t\tString message = \"Failed to transform configuration parameter with key '%s' and initial value '%s'\".formatted(\n\t\t\t\t\tkey, input);\n\t\t\t\tthrow new JUnitException(message, ex);\n\t\t\t}\n\t\t});\n\t}\n\n\t/**\n\t * Get the keys of all configuration parameters stored in this\n\t * {@code ConfigurationParameters}.\n\t *\n\t * @return the set of keys contained in this {@code ConfigurationParameters}\n\t */\n\t@API(status = STABLE, since = \"1.9\")\n\tSet<String> keySet();\n\n}\n","sourceCodeStart":111,"sourceCodeEnd":144,"githubUrl":"https://github.com/junit-team/junit5/blob/956246301e03d757539f7b76dd5a91f298637563/junit-platform-engine/src/main/java/org/junit/platform/engine/ConfigurationParameters.java#L111-L144","documentation":"Thrown by the ConfigurationParameters.get(String, Function) default method (line 120-132) when the user-supplied transformer throws any exception while converting a configuration parameter value. The library wraps the original exception in a JUnitException so callers get a single, consistent failure type naming the offending key and initial value. This is the standard mechanism for engines/extensions that parse typed config values (e.g. integers, durations).","triggerScenarios":"Calling configurationParameters.get(\"some.key\", Integer::valueOf) where the resolved value is non-numeric; any transformer lambda (Duration.parse, URI::new, custom parser) that throws on the stored value. The value comes from the layered lookup: direct params, then JVM system property, then junit-platform.properties.","commonSituations":"Setting junit.platform.* properties to invalid values (e.g. junit.jupiter.execution.parallel.config.fixed.parallelism=abc); a system property -Djunit.jupiter.conditions.deactivate=malformed colliding with a transformer; version upgrades that change accepted formats; typos in junit-platform.properties.","solutions":["Read the caused-by exception to identify the parse failure and the exact value, then correct the property in junit-platform.properties or the JVM system property.","Make your transformer defensive: sanitize/validate the raw string before parsing, or return null (treated as absent) instead of throwing.","Confirm whether the value originates from junit-platform.properties, a system property, or a programmatic LauncherFactory request and fix it at that source.","Run with debug logging to see which ConfigurationParameters key is being transformed when the error surfaces deep in engine code."],"exampleFix":"// before\nint parallelism = config.get(\"fixed.parallelism\", Integer::valueOf).orElse(1); // throws on 'abc'\n\n// after\nint parallelism = config.get(\"fixed.parallelism\", raw -> {\n    try { return Integer.valueOf(raw); }\n    catch (NumberFormatException e) { return null; } // treated as absent\n}).orElse(1);\n// and in junit-platform.properties: fixed.parallelism=4","handlingStrategy":"try-catch","validationCode":"// Validate the value parses *before* handing it to the framework transformer\nOptional<String> raw = config.get(\"my.key\");\nif (raw.isPresent()) {\n    try { Integer.parseInt(raw.get()); }\n    catch (NumberFormatException e) { throw new IllegalStateException(\"my.key must be integer: \" + raw.get(), e); }\n}","typeGuard":null,"tryCatchPattern":"try {\n    return config.get(\"my.key\", Integer::valueOf).orElse(defaultValue);\n} catch (JUnitException e) {\n    // caused-by has the real parse error\n    log.warn(\"bad value for my.key, using default\", e.getCause());\n    return defaultValue;\n}","preventionTips":["Validate junit-platform.properties values in a startup smoke check.","Use defensive transformers that return null (treated as absent) on parse failure instead of throwing.","Keep a single source of truth for each configuration parameter's parser."],"tags":["junit-platform","configuration","config-parameters","parsing"],"analyzedSha":"956246301e03d757539f7b76dd5a91f298637563","analyzedAt":"2026-08-04T19:25:17.049Z","schemaVersion":2}