conductor-oss/conductor · warning · IOException

A2A stream interrupted

Error message

A2A stream interrupted

What it means

Thrown by A2AWorkflowAgent.sleep() when the thread sleeping between SSE event emissions is interrupted. The InterruptedException is caught, the interrupt flag is restored (Thread.currentThread().interrupt()), and it is re-thrown as an IOException with message 'A2A stream interrupted'. This occurs in the A2A server (agent side), not the client side.

Source

Thrown at ai/src/main/java/org/conductoross/conductor/ai/a2a/server/A2AWorkflowAgent.java:335

        event.put("final", isFinal);
        return event;
    }

    private Map<String, Object> artifactUpdate(A2ATask task, Artifact artifact) {
        Map<String, Object> event = new HashMap<>();
        event.put("kind", "artifact-update");
        event.put("taskId", task.getId());
        event.put("contextId", task.getContextId());
        event.put("artifact", artifact);
        return event;
    }

    private void sleep(long millis) throws IOException {
        try {
            Thread.sleep(millis);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            throw new IOException("A2A stream interrupted", e);
        }
    }

    // ---- mapping -----------------------------------------------------------------------------

    private A2ATask toA2ATask(Workflow workflow) {
        A2ATask task = new A2ATask();
        task.setKind("task");
        task.setId(workflow.getWorkflowId());
        task.setContextId(workflow.getCorrelationId());

        String state = mapState(workflow);
        TaskStatus status = new TaskStatus();
        status.setState(state);
        String note = statusNote(workflow, state);
        if (note != null) {
            status.setMessage(agentTextMessage(note, workflow));
        }

View on GitHub (pinned to cf7c3e4a8a)

Solutions

  1. This is typically an expected interruption when a client disconnects or a workflow is cancelled — check if the workflow was intentionally terminated
  2. Verify there are no premature connection drops caused by proxy/load-balancer idle timeouts
  3. If using a reverse proxy, ensure idle timeout is longer than expected stream duration
  4. Ensure the client maintains the connection for the full streaming duration
Defensive patterns

Strategy: try-catch

Validate before calling

// This is server-side — ensure the client maintains the connection
// for the full streaming duration. No client-side validation prevents it.

Try / catch

// In the A2AWorkflowAgent streaming handler
try {
    // streaming loop with sleep()
} catch (IOException e) {
    if ("A2A stream interrupted".equals(e.getMessage())) {
        // Thread was interrupted — likely client disconnected or workflow cancelled
        log.info("A2A stream interrupted, closing gracefully");
        // Clean up resources and return — no need to re-throw for expected interruptions
    } else {
        throw e;
    }
}

Prevention

When it happens

Trigger: During A2AWorkflowAgent streaming, the sleep() method between event emissions is interrupted by another thread calling Thread.interrupt() on the streaming thread. This can happen when the workflow is cancelled, the HTTP connection is closed by the client, or the server is shutting down.

Common situations: The A2A client (remote agent caller) disconnects mid-stream, causing the servlet container to interrupt the streaming thread. The underlying Conductor workflow is terminated or cancelled. Server shutdown or thread pool eviction interrupts the streaming thread. A timeout on the HTTP response triggers interruption.

Related errors


AI-assisted analysis of conductor-oss/conductor@cf7c3e4a8a (2026-08-14). Data as JSON: /api/errors/8ed9c468ac65cf4f. Report an issue: GitHub.