github/copilot-sdk · error · IllegalArgumentException
schema cannot be combined with defaultValue — express…
Error message
schema cannot be combined with defaultValue — express defaults inside the schema if needed
What it means
A Param's schema and defaultValue are mutually exclusive: when a JSON object schema is supplied, any default value must be expressed inside the schema itself. If both a non-empty schema and a non-empty defaultValue are set, the constructor throws this IllegalArgumentException (em-dash in message). This keeps the schema the single source of truth for defaults.
Solutions
- Remove the defaultValue and declare the default in the schema (e.g. via a "default" keyword) if supported.
- Drop the schema if the defaultValue-based declaration style is what you want.
- Grep tool declarations for params setting both fields and fix them before deployment.
Example fix
// before
new Param("q", "desc", Type.STRING, "hello", false, "{\"type\":\"object\"}");
// after
new Param("q", "desc", Type.STRING, null, false, "{\"type\":\"object\"}"); Defensive patterns
Strategy: validation
Validate before calling
static Param schemaOnlyParam(String name, String desc, Class<?> type, String schema) {
if (schema != null && !schema.isEmpty())
return new Param(name, desc, type, null, false, schema); // defaults live in the schema
return new Param(name, desc, type, null, false, null);
} Try / catch
try {
new Param(name, desc, type, def, false, schema);
} catch (IllegalArgumentException e) {
if (e.getMessage().contains("schema cannot be combined with defaultValue")) {
// choose one style: either schema (put default inside) or defaultValue
}
throw e;
} Prevention
- Pick one default-expression style per codebase: schema-embedded or defaultValue, never both.
- During migration to schemas, strip old defaultValue fields in the same change.
- Lint tool declarations for params that set both fields.
When it happens
Trigger: new Param(..., defaultValue="x", schema="{...}") — any combination of non-empty schema plus non-empty defaultValue.
Common situations: Migrating existing params to schema-based definitions while leaving the old defaultValue in place; mixing two configuration styles when declaring Copilot tool parameters.
Related errors
- required=true cannot be combined with a non-empty…
- schema must be a valid JSON object string
- setModel cannot combine an explicit autoTier with…
- must not be null or blank
- must be 'true' or 'false'
AI-assisted analysis of github/copilot-sdk@cd8cf15dc3 (2026-09-09).
Data as JSON: /api/errors/1cf8a9c51804093f.
Report an issue: GitHub.
Appendix: source
Thrown at java/sdk/src/main/java/com/github/copilot/tool/Param.java:62
this.type = Objects.requireNonNull(type, "type");
this.name = requireNonBlank(name, "name");
this.description = requireNonBlank(description, "description");
this.defaultValue = defaultValue == null ? "" : defaultValue;
this.schema = schema == null ? "" : schema;
this.required = required;
if (this.required && !this.defaultValue.isEmpty()) {
throw new IllegalArgumentException("required=true cannot be combined with a non-empty defaultValue");
}
if (!this.schema.isEmpty()) {
String trimmed = this.schema.trim();
if (!trimmed.startsWith("{") || !trimmed.endsWith("}")) {
throw new IllegalArgumentException(
"schema must be a valid JSON object string (must start with '{' and end with '}')");
}
if (!this.defaultValue.isEmpty()) {
throw new IllegalArgumentException(
"schema cannot be combined with defaultValue — express defaults inside the schema if needed");
}
}
validateDefaultValue(type, this.defaultValue);
}
/**
* Creates a required parameter with no default value.
*
* @param <T>
* the parameter type
* @param type
* the Java class of the parameter
* @param name
* the wire name sent to the model (must not be blank)
* @param description
* a human-readable description (must not be blank)View on GitHub (pinned to cd8cf15dc3)