github/copilot-sdk · error · IllegalStateException
Failed to invoke + metaClassName + .definitions()
Error message
Failed to invoke + metaClassName + .definitions()
What it means
After locating the generated $$CopilotToolMeta class, loadDefinitions instantiates it and calls its definitions() method reflectively. Any ReflectiveOperationException during that step (constructor not accessible, instantiation failure, invocation error) is wrapped in this IllegalStateException. Unlike error 225, the metadata class exists but could not be constructed or invoked.
Solutions
- Run a clean rebuild so generated metadata and SDK version are in sync.
- Align the copilot-sdk-java version used at compile time (processor) and runtime in all modules.
- Check the cause (ex.getCause()) — if the meta-class constructor threw, fix the underlying initialization error in the tool class.
- Verify the tool classes' jar actually contains the freshly generated meta classes and is not a stale artifact.
Example fix
// before (build.gradle) implementation 'com.github.copilot:copilot-sdk-java:1.0.0' // lib module still compiles against 0.9.0 → stale meta class // after (build.gradle) // same version everywhere def copilotSdk = 'com.github.copilot:copilot-sdk-java:1.2.0' implementation copilotSdk annotationProcessor copilotSdk
Defensive patterns
Strategy: try-catch
Validate before calling
// ensure compile & runtime SDK versions match in the build script before registration
Try / catch
try { defs = ToolDefinition.fromObject(new Tools()); }
catch (IllegalStateException e) {
log.error("failed to invoke generated metadata for {}", e.getCause(), e);
throw e;
} Prevention
- Keep one copilot-sdk-java version across all modules (use a version property/BOM).
- Clean rebuild after SDK upgrades so generated metadata matches.
- Read e.getCause() to find constructor/initialization failures early.
When it happens
Trigger: The generated meta class exists but its no-arg constructor fails (e.g. its own initialization throws), the class was compiled against an incompatible SDK version so definitions() has an unexpected signature, or classloader/visibility issues prevent instantiation.
Common situations: Mixing SDK versions: tool classes compiled against an older copilot-sdk-java but running with a newer SDK (or vice versa) so the generated code's expected interface changed; hot-swap/incremental recompiles leaving stale generated classes; classloader isolation in app servers preventing instantiation.
Related errors
- fromClass() requires all @CopilotTool methods to be static…
- SDK protocol version mismatch: SDK supports versions
- clazz must not be null
- Generated class + metaClassName + not found. Ensure the…
- Unknown WorkspaceDiffFileChangeType value
AI-assisted analysis of github/copilot-sdk@cd8cf15dc3 (2026-09-09).
Data as JSON: /api/errors/3c8dbf8d8619f1b1.
Report an issue: GitHub.
Appendix: source
Thrown at java/sdk/src/main/java/com/github/copilot/rpc/ToolDefinition.java:937
if (handler == null) {
throw new IllegalArgumentException("handler must not be null for tool '" + toolName + "'");
}
}
@SuppressWarnings("unchecked")
private static List<ToolDefinition> loadDefinitions(Class<?> clazz, Object instance) {
String metaClassName = clazz.getName() + "$$CopilotToolMeta";
try {
Class<?> metaClass = Class.forName(metaClassName, true, clazz.getClassLoader());
var provider = (com.github.copilot.tool.CopilotToolMetadataProvider<Object>) metaClass
.getDeclaredConstructor().newInstance();
return provider.definitions(instance, getConfiguredMapper());
} catch (ClassNotFoundException e) {
throw new IllegalStateException("Generated class " + metaClassName + " not found. "
+ "Ensure the CopilotToolProcessor annotation processor ran during compilation. "
+ "Add the copilot-sdk-java dependency to your annotation processor path.", e);
} catch (ReflectiveOperationException e) {
throw new IllegalStateException("Failed to invoke " + metaClassName + ".definitions()", e);
}
}
/**
* Returns the SDK-configured ObjectMapper for tool argument/result
* serialization. Configuration mirrors
* {@code JsonRpcClient.createObjectMapper()}.
*/
private static ObjectMapper getConfiguredMapper() {
return ConfiguredMapperHolder.INSTANCE;
}
/**
* Lazy holder for the configured ObjectMapper (thread-safe, initialized on
* first access).
*/
private static final class ConfiguredMapperHolder {
static final ObjectMapper INSTANCE = createMapper();View on GitHub (pinned to cd8cf15dc3)