github/copilot-sdk · error · IllegalStateException
Generated class + metaClassName + not found. Ensure the…
Error message
Generated class + metaClassName + not found. Ensure the CopilotToolProcessor annotation processor ran during compilation. Add the copilot-sdk-java dependency to your annotation processor path.
What it means
Tool registration via fromObject/fromClass depends on the CopilotToolProcessor annotation processor generating a 'ClassName$$CopilotToolMeta' metadata class at compile time. loadDefinitions loads this generated class reflectively; if it is absent (ClassNotFoundException), this IllegalStateException is thrown explaining that the annotation processor did not run and pointing at the annotation-processor path setup.
Solutions
- Add copilot-sdk-java to your build's annotation processor path: in Maven, annotationProcessorPaths under maven-compiler-plugin; in Gradle, annotationProcessor 'com.github.copilot:copilot-sdk-java'.
- Verify the generated class exists in target/classes (or build/classes) after compilation: look for YourClass$$CopilotToolMeta.class.
- Run a clean rebuild (mvn clean compile / gradle clean build) to regenerate metadata after build-config changes.
- Check the compiler isn't running with -proc:none and that IDE annotation processing is enabled.
Example fix
// before (pom.xml)
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration><annotationProcessorPaths/></configuration>
</plugin>
// after (pom.xml)
<annotationProcessorPaths>
<path>
<groupId>com.github.copilot</groupId>
<artifactId>copilot-sdk-java</artifactId>
<version>1.0.0</version>
</path>
</annotationProcessorPaths> Defensive patterns
Strategy: validation
Validate before calling
String meta = Tools.class.getName() + "$$CopilotToolMeta";
try { Class.forName(meta, false, Tools.class.getClassLoader()); }
catch (ClassNotFoundException e) { throw new IllegalStateException("annotation processor did not run for " + meta); } Try / catch
try { defs = ToolDefinition.fromObject(new Tools()); } catch (IllegalStateException e) {
log.error("metadata missing — check annotation processor config", e);
throw e;
} Prevention
- Configure the copilot-sdk-java processor in annotationProcessorPaths (Maven) or annotationProcessor (Gradle) from day one.
- Enable annotation processing in the IDE build settings.
- Add a smoke test that loads $$CopilotToolMeta classes after compilation.
- Always run clean builds in CI so generated sources are regenerated.
When it happens
Trigger: Using ToolDefinition.fromObject(new X()) or fromClass(X.class) on a class annotated with @CopilotTool whose $$CopilotToolMeta class was never generated: processor not on the annotation processor path, compilation with -proc:none, incremental-build staleness, or running an old jar built before processing was configured.
Common situations: Maven/Gradle builds missing the copilot-sdk-java processor dependency in annotationProcessorPaths/annotationProcessor configuration; IDE builds (IntelliJ/Eclipse) with annotation processing disabled; clean-checkout CI builds missing the processor configuration that only existed on a developer machine; shading/repackaging that strips generated classes.
Related errors
- Runtime asset not found on classpath:
- Classpath resource is empty:
- fromClass() requires all @CopilotTool methods to be static…
- Failed to invoke + metaClassName + .definitions()
- Unknown WorkspaceDiffFileChangeType value
AI-assisted analysis of github/copilot-sdk@cd8cf15dc3 (2026-09-09).
Data as JSON: /api/errors/c3c4c986aa62d123.
Report an issue: GitHub.
Appendix: source
Thrown at java/sdk/src/main/java/com/github/copilot/rpc/ToolDefinition.java:933
}
}
private static void requireNonNullHandler(Object handler, String toolName) {
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 onView on GitHub (pinned to cd8cf15dc3)