{"record":{"id":"6973d81055abba3d","repo":"NationalSecurityAgency/ghidra","slug":"type-errors-typeerrors","errorCode":null,"errorMessage":"Type errors: {typeErrors}","messagePattern":"Type errors: (.+?)","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/tracermi/LaunchParameter.java","lineNumber":79,"sourceCode":"\t\t\tSet<String> extraneous = new TreeSet<>(arguments.keySet());\n\t\t\textraneous.removeAll(parameters.keySet());\n\t\t\tthrow new IllegalArgumentException(\"Extraneous parameters: \" + extraneous);\n\t\t}\n\n\t\tMap<String, String> typeErrors = null;\n\t\tfor (Map.Entry<String, ValStr<?>> ent : arguments.entrySet()) {\n\t\t\tString name = ent.getKey();\n\t\t\tValStr<?> val = ent.getValue();\n\t\t\tLaunchParameter<?> param = parameters.get(name);\n\t\t\tif (val.val() != null && !param.type.isAssignableFrom(val.val().getClass())) {\n\t\t\t\tif (typeErrors == null) {\n\t\t\t\t\ttypeErrors = new LinkedHashMap<>();\n\t\t\t\t}\n\t\t\t\ttypeErrors.put(name, \"val '%s' is not a %s\".formatted(val.val(), param.type()));\n\t\t\t}\n\t\t}\n\t\tif (typeErrors != null) {\n\t\t\tthrow new IllegalArgumentException(\"Type errors: \" + typeErrors);\n\t\t}\n\t\treturn arguments;\n\t}\n\n\tpublic static Map<String, LaunchParameter<?>> mapOf(LaunchParameter<?>... parameters) {\n\t\treturn mapOf(Arrays.asList(parameters));\n\t}\n\n\tpublic ValStr<T> decode(String string) {\n\t\treturn decoder.decodeValStr(string);\n\t}\n\n\tpublic ValStr<T> get(Map<String, ValStr<?>> arguments) {\n\t\tif (arguments.containsKey(name)) {\n\t\t\treturn ValStr.cast(type, arguments.get(name));\n\t\t}\n\t\tif (required) {\n\t\t\tthrow new IllegalArgumentException(","sourceCodeStart":61,"sourceCodeEnd":97,"githubUrl":"https://github.com/NationalSecurityAgency/ghidra/blob/d5f144c24d6bc53c9cbf4448c6d11143e7696206/Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/tracermi/LaunchParameter.java#L61-L97","documentation":"Thrown as IllegalArgumentException by LaunchParameter.validateArguments (LaunchParameter.java:66-80) when one or more argument values have a runtime type not assignable to the declared LaunchParameter type. Errors are accumulated into a LinkedHashMap (name -> 'val ... is not a ...') and reported together, so all type mismatches in one call are listed at once.","triggerScenarios":"Calling validateArguments with a value whose class is not assignable to param.type: e.g. a String where an Integer is declared, a Long where a String is declared, or a custom object where a primitive wrapper is expected. val.val() must be non-null (null values skip the check).","commonSituations":"A launch.properties value parsed as the wrong type (string vs number); a UI field that returns text for a numeric parameter; a connector/launcher whose declared types changed; passing a boxed type the parameter does not accept.","solutions":["Convert each argument value to the declared parameter type before calling validateArguments.","Inspect the declared param.type() for each failing name and align the value's class.","For string-sourced input, decode using the parameter's own decoder (LaunchParameter.decode) which yields the correct ValStr type."],"exampleFix":"// before\nLaunchParameter<Integer> pPort = LaunchParameter.required(\"port\", Integer.class, ...);\nvalidateArguments(\n  Map.of(\"port\", pPort),\n  Map.of(\"port\", new ValStr<>(\"8080\", null))); // String, not Integer -> Type error\n\n// after\nvalidateArguments(\n  Map.of(\"port\", pPort),\n  Map.of(\"port\", new ValStr<>(8080, null))); // Integer matches","handlingStrategy":"type-guard","validationCode":"for (Map.Entry<String, ValStr<?>> e : arguments.entrySet()) {\n    LaunchParameter<?> p = parameters.get(e.getKey());\n    Object v = e.getValue().val();\n    if (v != null && !p.type().isAssignableFrom(v.getClass())) {\n        throw new IllegalArgumentException(e.getKey() + \": expected \" + p.type());\n    }\n}","typeGuard":"boolean typesMatch(Map<String, LaunchParameter<?>> params, Map<String, ValStr<?>> args) {\n    for (var e : args.entrySet()) {\n        Object v = e.getValue().val();\n        if (v == null) continue;\n        if (!params.get(e.getKey()).type().isAssignableFrom(v.getClass())) return false;\n    }\n    return true;\n}","tryCatchPattern":"try {\n    LaunchParameter.validateArguments(parameters, arguments);\n} catch (IllegalArgumentException e) {\n    if (e.getMessage().startsWith(\"Type errors\")) {\n        for (var ent : arguments.entrySet()) {\n            LaunchParameter<?> p = parameters.get(ent.getKey());\n            ent.setValue(p.decode(String.valueOf(ent.getValue().val())));\n        }\n        LaunchParameter.validateArguments(parameters, arguments);\n    } else throw e;\n}","preventionTips":["Decode string-sourced values with LaunchParameter.decode to get the correct type.","Match each value's class to the declared param.type() before validating.","Treat type changes in declared parameters as breaking and migrate callers."],"tags":["launch-parameter","type-validation","trace-rmi","java"],"backgroundTag":null,"analyzedSha":"d5f144c24d6bc53c9cbf4448c6d11143e7696206","analyzedAt":"2026-08-14T01:00:57.564Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}