github/copilot-sdk · error · IllegalArgumentException

must not be null or blank

Error message

<fieldName> must not be null or blank

What it means

Param's static requireNonBlank helper rejects null or isBlank() strings for mandatory text fields (name, description, etc.), throwing IllegalArgumentException with '<fieldName> must not be null or blank'. The message embeds the field name so the offending parameter is identified. It runs in the Param constructor, so failure happens at tool-declaration time, not call time.

Solutions

  1. Provide a non-blank value for the named field before constructing the Param.
  2. Sanitize generated values: trim and reject blanks upstream of Param construction.
  3. Catch IllegalArgumentException at registration time to fail fast with the field name in the log.

Example fix

// before
new Param(config.get("name"), "desc", Type.STRING, null, false, null); // name may be null
// after
String name = Objects.requireNonNullElse(config.get("name"), "unnamed").trim();
if (name.isEmpty()) throw new ConfigurationException("param name missing");
new Param(name, "desc", Type.STRING, null, false, null);
Defensive patterns

Strategy: validation

Validate before calling

static String requireText(String v, String field) {
    if (v == null || v.isBlank()) throw new IllegalArgumentException(field + " is required");
    return v.trim();
}
// usage: new Param(requireText(name, "name"), requireText(desc, "description"), ...)

Type guard

static boolean nonBlank(String s) { return s != null && !s.isBlank(); }

Try / catch

try {
    params.add(new Param(name, desc, type, def, req, schema));
} catch (IllegalArgumentException e) {
    if (e.getMessage().endsWith("must not be null or blank")) {
        throw new ToolDefinitionException("Bad parameter definition: " + e.getMessage(), e);
    }
    throw e;
}

Prevention

When it happens

Trigger: new Param(null, "desc", ...) — name null; new Param("", "desc", ...) — name blank; same for description or any field routed through requireNonBlank (values like " " count as blank).

Common situations: Programmatically generated parameter lists where a name comes from an empty map entry or missing config; refactors that pass description strings through a formatter returning empty output.

Understand the failure class

Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.

Related errors


AI-assisted analysis of github/copilot-sdk@cd8cf15dc3 (2026-09-09). Data as JSON: /api/errors/c573fbd960a46266. Report an issue: GitHub.

Appendix: source

Thrown at java/sdk/src/main/java/com/github/copilot/tool/Param.java:237

    }

    @Override
    public int hashCode() {
        return Objects.hash(type, name, description, required, defaultValue, schema);
    }

    @Override
    public String toString() {
        return "Param[name=" + name + ", type=" + type.getSimpleName() + ", required=" + required + "]";
    }

    // ------------------------------------------------------------------
    // Internal validation helpers
    // ------------------------------------------------------------------

    private static String requireNonBlank(String value, String fieldName) {
        if (value == null || value.isBlank()) {
            throw new IllegalArgumentException(fieldName + " must not be null or blank");
        }
        return value;
    }

    @SuppressWarnings({"rawtypes", "unchecked"})
    private static <T> void validateDefaultValue(Class<T> type, String defaultValue) {
        if (defaultValue == null || defaultValue.isEmpty()) {
            return;
        }

        try {
            if (type == String.class) {
                return;
            }
            if (type == Integer.class || type == int.class) {
                Integer.parseInt(defaultValue);
                return;
            }

View on GitHub (pinned to cd8cf15dc3)