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

  1. Remove the defaultValue and declare the default in the schema (e.g. via a "default" keyword) if supported.
  2. Drop the schema if the defaultValue-based declaration style is what you want.
  3. 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

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


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)