Skip to content

Framework-agent failures return None instead of the failed task's reason #483

Description

@ambiorix2099

In short: when a framework agent fails, the SDK prints None instead of the reason — even though the server recorded a perfectly good one. Every such failure costs a manual walk of the server API to diagnose.

File: src/conductor/ai/agents/runtime/runtime.py

Symptom

$ CONDUCTOR_AGENT_LLM_MODEL=anthropic/claude-sonnet-4-6 python examples/agents/93_openai_runner_hello_world.py
Framework agent 'Assistant' execution FAILED
None

No reason, no task name, nothing actionable. Diagnosing it means walking the server API by hand:

curl -s localhost:8080/api/agent/executions?size=20
curl -s "localhost:8080/api/workflow/<executionId>?includeTasks=true"   # find FAILED tasks, read reasonForIncompletion

Cause

_run_framework() reports:

error=status.reason if raw_status in ("FAILED", "TERMINATED") else None

For these failures status.reason is empty, so the result is None.

The reason was available all along, at both levels of the execution:

  • the workflow's own reasonForIncompletion:
    Task 41830611-7c25-4d51-a36f-50e324e59239 failed with status: FAILED and reason:
    'Task execution failed: OpenAI Responses API call failed: Responses API failed with status 401 ...'
    
  • the failed task's reasonForIncompletion (Assistant_llm), carrying the same text.

There is also an existing helper that already does this. _extract_failed_task_reason(wf) reads the first FAILED task's reasonForIncompletion and returns Task '<ref>' failed: <reason>. It is called by run() (line ~2534) and _run_by_name() (line ~2623) — which is why native-agent failures report properly, e.g. 54_software_bug_assistant prints:

ERROR: Task 'software_assistant_54_list_mcp_0' failed: Failed to list MCP tools ... HTTP 400

_run_framework() never calls it.

Fix

When status.reason is empty, fall back to the workflow's reasonForIncompletion, or call _extract_failed_task_reason as run() does. Either is sufficient.

Verify

Start the server without OPENAI_API_KEY, run 93 — it should name the failing task and its reason instead of printing None.

Note — possible second gap, unconfirmed

59_coding_agent goes through run() yet also reported no reason, while its server-side SUB_WORKFLOW task did carry one (Anthropic Messages API failed with status 404). _extract_failed_task_reason only inspects the top-level workflow's tasks, so failures inside a sub-workflow may need the same treatment. Worth checking while fixing this.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions