{"record":{"id":"11e5e51abf0c525a","repo":"github/copilot-sdk","slug":"required-true-cannot-be-combined-with-a-non-empty","errorCode":null,"errorMessage":"required=true cannot be combined with a non-empty defaultValue","messagePattern":"required=true cannot be combined with a non-empty defaultValue","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"java/sdk/src/main/java/com/github/copilot/tool/Param.java","lineNumber":52,"sourceCode":"\n    private final Class<T> type;\n    private final String name;\n    private final String description;\n    private final boolean required;\n    private final String defaultValue;\n    private final String schema;\n\n    private Param(Class<T> type, String name, String description, boolean required, String defaultValue,\n            String schema) {\n        this.type = Objects.requireNonNull(type, \"type\");\n        this.name = requireNonBlank(name, \"name\");\n        this.description = requireNonBlank(description, \"description\");\n        this.defaultValue = defaultValue == null ? \"\" : defaultValue;\n        this.schema = schema == null ? \"\" : schema;\n        this.required = required;\n\n        if (this.required && !this.defaultValue.isEmpty()) {\n            throw new IllegalArgumentException(\"required=true cannot be combined with a non-empty defaultValue\");\n        }\n\n        if (!this.schema.isEmpty()) {\n            String trimmed = this.schema.trim();\n            if (!trimmed.startsWith(\"{\") || !trimmed.endsWith(\"}\")) {\n                throw new IllegalArgumentException(\n                        \"schema must be a valid JSON object string (must start with '{' and end with '}')\");\n            }\n            if (!this.defaultValue.isEmpty()) {\n                throw new IllegalArgumentException(\n                        \"schema cannot be combined with defaultValue — express defaults inside the schema if needed\");\n            }\n        }\n\n        validateDefaultValue(type, this.defaultValue);\n    }\n\n    /**","sourceCodeStart":34,"sourceCodeEnd":70,"githubUrl":"https://github.com/github/copilot-sdk/blob/cd8cf15dc3f9e762615790aaed0a771a0f392755/java/sdk/src/main/java/com/github/copilot/tool/Param.java#L34-L70","documentation":"Param's constructor enforces mutual exclusivity between required=true and a non-empty defaultValue: a parameter cannot be both mandatory and have a default. If the builder/constructor receives required=true together with a defaultValue string that is non-empty after null-coalescing, it throws this IllegalArgumentException. This is a declarative API contract check, not a parse-time issue.","triggerScenarios":"new Param(..., required=true, defaultValue=\"5\", ...) or builder .required(true).defaultValue(\"5\") on any Param used to declare a Copilot tool parameter.","commonSituations":"Copy-pasting a parameter definition and toggling required without clearing the default; assuming an empty-string default means 'no default' (it does — null coalesces to \"\" but any non-empty string conflicts).","solutions":["Set required=false if the parameter should fall back to the defaultValue.","Remove the defaultValue (pass null) if the parameter is genuinely required.","Add a unit test over Param declarations to catch this combination at startup."],"exampleFix":"// before\nnew Param(\"count\", \"desc\", Type.INT, \"5\", true, null);\n// after\nnew Param(\"count\", \"desc\", Type.INT, null, true, null);","handlingStrategy":"validation","validationCode":"static Param safeParam(String name, String desc, Class<?> type, String defaultValue, boolean required, String schema) {\n    if (required && defaultValue != null && !defaultValue.isEmpty())\n        throw new IllegalArgumentException(\"param '\" + name + \"': required=true conflicts with defaultValue\");\n    return new Param(name, desc, type, defaultValue, required, schema);\n}","typeGuard":null,"tryCatchPattern":"try {\n    registry.register(new Param(name, desc, type, def, required, schema));\n} catch (IllegalArgumentException e) {\n    if (e.getMessage().contains(\"required=true cannot be combined\")) {\n        registry.register(new Param(name, desc, type, null, required, schema)); // drop default\n        return;\n    }\n    throw e;\n}","preventionTips":["Treat 'required' and 'defaultValue' as mutually exclusive in your parameter DSL.","Add a startup test that constructs every declared Param.","When toggling required on a copied Param, clear defaultValue at the same time."],"tags":["validation","tool-parameters","conflicting-options","java"],"backgroundTag":"conflicting-config-options","analyzedSha":"cd8cf15dc3f9e762615790aaed0a771a0f392755","analyzedAt":"2026-09-09T18:32:31.973Z","contentChangedAt":"2026-09-09T18:32:31.973Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}