A2A protocol integration for Embabel Agent Framework enabling agent-to-agent communication
Solutions to common issues.
Symptoms: 404 errors when accessing /a2a/.well-known/agent.json or /a2a
Check Logs:
INFO c.e.a.a.s.A2AEndpointRegistrar - Registering 1 A2A endpoints
INFO c.e.a.a.s.A2AEndpointRegistrar - Registering web endpoint under /a2a/.well-known/agent.jsonSolution 1: Ensure component scanning includes A2A packages
@SpringBootApplication
@ComponentScan(basePackages = [
"com.embabel.agent.a2a",
"your.application.package"
])
class ApplicationSolution 2: Verify AgentCardHandler bean exists
@Autowired
lateinit var agentCardHandler: AgentCardHandler // Should inject successfullySymptoms: Bean injection fails with "No qualifying bean of type 'AgentCardHandler'"
Solution: Check A2AConfiguration is being scanned. Explicitly import if needed:
@SpringBootApplication
@Import(A2AConfiguration::class)
class ApplicationSymptoms: Only one handler responds, or unexpected behavior
Solution: Ensure each AgentCardHandler has unique path:
@Bean
fun handler1(...): AgentCardHandler =
EmbabelServerGoalsAgentCardHandler(path = "a2a-public", ...)
@Bean
fun handler2(...): AgentCardHandler =
EmbabelServerGoalsAgentCardHandler(path = "a2a-partner", ...)Symptoms:
NoClassDefFoundError: com/embabel/agent/core/AgentPlatform
NoClassDefFoundError: com/embabel/agent/api/AutonomySolution: Add required Embabel dependencies:
<dependency>
<groupId>com.embabel.agent</groupId>
<artifactId>embabel-agent-core</artifactId>
<version>VERSION</version>
</dependency>
<dependency>
<groupId>com.embabel.agent</groupId>
<artifactId>embabel-agent-api</artifactId>
<version>VERSION</version>
</dependency>Symptoms: Streaming requests return regular responses or errors
Solution 1: Ensure Accept header is set:
curl -H "Accept: text/event-stream" ...Solution 2: Check method is streaming variant:
{
"method": "message/stream", // Not "message/send"
...
}Solution 3: Verify SseEmitter timeout configuration:
@Configuration
class WebMvcConfig : WebMvcConfigurer {
override fun configureAsyncSupport(configurer: AsyncSupportConfigurer) {
configurer.setDefaultTimeout(Long.MAX_VALUE)
}
}Symptoms:
Failed to deserialize request
JSONRPCErrorResponse with code 500Solution: Verify request format matches A2A specification:
{
"jsonrpc": "2.0",
"id": "request-id",
"method": "message/send",
"params": {
"message": {
"messageId": "m1",
"role": "user",
"parts": [{"text": "..."}]
}
}
}Symptoms: IllegalArgumentException: Task not found: task-id
Causes:
Solution: Check task exists before resubscribing:
if (taskStateManager.taskExists(taskId)) {
val emitter = streamingHandler.resubscribeToTask(taskId, newStreamId)
} else {
throw IllegalArgumentException("Task not found: $taskId")
}Symptoms: Event listeners not receiving A2ARequestEvent or A2AResponseEvent
Solution 1: Ensure @Component or @EventListener annotations:
@Component
class MyListener {
@EventListener
fun onRequest(event: A2ARequestEvent) { /* ... */ }
}Solution 2: Check AgenticEventListener is configured in Embabel framework
Symptoms: 401/403 errors when accessing .well-known/agent.json
Solution: Allow public access to AgentCard endpoint:
@Configuration
@EnableWebSecurity
class SecurityConfig {
@Bean
fun filterChain(http: HttpSecurity): SecurityFilterChain {
http.authorizeHttpRequests { auth ->
auth
.requestMatchers("/*/.well-known/agent.json").permitAll()
.requestMatchers("/*/").authenticated()
}
return http.build()
}
}Symptoms: Endpoints expected at /a2a but actual path is /app/a2a
Cause: Application has context path configured:
server:
servlet:
context-path: /appSolution: Endpoints are automatically at {context-path}/{handler-path}:
/app/a2a/.well-known/agent.json/app/a2aUpdate client URLs accordingly.
Symptoms: AgentCard has empty skills array
Solution: Verify goal filter logic:
// Debug: Log filtered goals
val filteredGoals = agentPlatform.goals.filter { goalFilter.invoke(it) }
logger.info("Filtered goals: {}", filteredGoals.map { it.name })
// Temporarily allow all goals to test
goalFilter = { true }Symptoms: Increasing memory usage over time, especially with many streaming requests
Solution: Schedule periodic cleanup:
@Component
class TaskCleanup(private val taskStateManager: TaskStateManager) {
@Scheduled(fixedRate = 3600000) // Every hour
fun cleanup() {
val cutoff = Instant.now().minus(Duration.ofHours(24))
taskStateManager.cleanupOldTasks(cutoff)
}
}Symptoms:
UnsupportedOperationException: Method task/get is not supported
UnsupportedOperationException: Method task/cancel is not supportedCause: These methods are not yet implemented in current version (0.3.3)
Implemented Methods:
message/send - Synchronous messagingmessage/stream - Streaming messagingtask/resubscribe - Resubscribe to existing tasktask/get - Not yet implementedtask/cancel - Not yet implementedSolution: Use implemented methods, or implement custom handler if needed.
tessl i tessl/maven-com-embabel-agent--embabel-agent-a2a@0.3.3