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
- Provide a non-blank value for the named field before constructing the Param.
- Sanitize generated values: trim and reject blanks upstream of Param construction.
- 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
- Validate names/descriptions at the config-loading boundary, before Param construction.
- Trim generated strings and reject whitespace-only values.
- Construct all Params in tests at CI time to fail fast on blank fields.
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
- required=true cannot be combined with a non-empty…
- schema must be a valid JSON object string
- schema cannot be combined with defaultValue — express…
- must be 'true' or 'false'
- invalid tool name: must not be empty
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)