ruvnet/ruflo · error

agent_execute failed

Error message

agent_execute failed

What it means

In a workflow 'task' step, executeAgentTask() (from agent-execute-core) returned { success: false } and this throw fires. 'agent_execute failed' is only the FALLBACK text used when result.error is empty — normally the real cause is propagated (e.g. 'Agent not found', 'Agent has been terminated', 'Anthropic API error 401: ...', 'Ollama API error ...', provider timeouts). Seeing the generic string means the failure path produced no message, so you must reproduce the agent call directly to learn why.

Source

Thrown at v3/@claude-flow/cli/src/mcp-tools/workflow-tools.ts:365

        let stepEntry: typeof stepResults[number] = { stepId: step.stepId, type: step.type, status: 'running' };

        try {
          if (step.type === 'task') {
            const cfg = step.config as Record<string, unknown>;
            const agentId = (cfg.agentId as string) || (workflow.variables.defaultAgentId as string);
            const promptTpl = (cfg.prompt as string) || step.name;
            if (!agentId) throw new Error(`task step ${step.stepId} requires config.agentId or workflow.variables.defaultAgentId`);
            const prompt = interp(promptTpl);
            const result = await executeAgentTask({
              agentId,
              prompt,
              systemPrompt: cfg.systemPrompt ? interp(String(cfg.systemPrompt)) : undefined,
              maxTokens: cfg.maxTokens as number | undefined,
              temperature: cfg.temperature as number | undefined,
              timeoutMs: cfg.timeoutMs as number | undefined,
            });
            if (!result.success) throw new Error(result.error || 'agent_execute failed');
            step.result = result;
            workflow.variables[`${step.stepId}.output`] = result.output;
            workflow.variables.lastStepOutput = result.output;
            stepEntry = { stepId: step.stepId, type: 'task', status: 'completed', durationMs: result.durationMs, output: result.output };
          } else if (step.type === 'wait') {
            const cfg = step.config as Record<string, unknown>;
            const ms = Math.min(Math.max(0, (cfg.ms as number) || 0), 60000);
            await new Promise(r => setTimeout(r, ms));
            step.result = { waitedMs: ms };
            stepEntry = { stepId: step.stepId, type: 'wait', status: 'completed', durationMs: ms };
          } else if (step.type === 'condition') {
            // Simple condition: config.when is a JS expression evaluated against workflow.variables.
            // For safety, we only support `var === 'value'` or `var === number`.
            const cfg = step.config as Record<string, unknown>;
            const expr = String(cfg.when || 'true').trim();
            const m = expr.match(/^([a-zA-Z_][\w]*)\s*===?\s*(['\"])?([^'\"]*)\2?$/);
            let truthy = false;
            if (m) {

View on GitHub (pinned to fa13ee4ad6)

Solutions

  1. Verify the agent exists and is not terminated: call agent_list / agent_status with the same agentId the step uses.
  2. Reproduce outside the workflow: call agent_execute with the same agentId and prompt — it returns the detailed error string.
  3. Check provider configuration (API keys env vars, Ollama reachable, providerLabel endpoints) for the agent's configured model/provider.
  4. If the direct call also yields an empty error, capture it as a bug — success:false with no message is a lost-error defect in the execute path.

Example fix

// before
{ type: 'task', config: { agentId: 'coder-42', prompt: '...' } } // coder-42 from an old session
// workflow run -> step failed: 'agent_execute failed'

// after
await mcp.call('agent_spawn', { agentType: 'coder', agentId: 'coder-42' }); // ensure it exists
await mcp.call('agent_execute', { agentId: 'coder-42', prompt: 'ping' });   // verify, see real error if any
// then run the workflow
Defensive patterns

Strategy: validation

Validate before calling

// Before workflow_run, confirm every referenced agent exists and is alive:
async function assertAgentsReady(agentIds: string[], mcp: McpClient): Promise<void> {
  const { agents } = await mcp.call('agent_list', {});
  const alive = new Map(agents.map((a: any) => [a.agentId, a.status]));
  for (const id of agentIds) {
    const status = alive.get(id);
    if (!status) throw new Error(`agent ${id} not found — spawn it before the run`);
    if (status === 'terminated') throw new Error(`agent ${id} is terminated — respawn before the run`);
  }
}

Type guard

interface AgentTaskResult { success: boolean; error?: string; output?: string }
function isFailedAgentResult(r: AgentTaskResult): r is AgentTaskResult & { success: false } {
  return r.success === false;
}

Try / catch

try {
  return await callTool('workflow_run', { workflowId });
} catch (e) {
  if ((e as Error).message === 'agent_execute failed') {
    // Generic fallback text: real cause was empty — reproduce directly for the detailed error
    const probe = await callTool('agent_execute', { agentId, prompt: 'ping' });
    return stepError(`agent_execute failed (no message); direct probe says: ${probe.error ?? 'ok now — transient provider issue'}`);
  }
  throw e;
}

Prevention

When it happens

Trigger: A task step whose agentId refers to a deleted or never-spawned agent; an agent whose status is 'terminated'; provider errors (bad/missing API key, 4xx/5xx from Anthropic/Ollama/custom provider); a provider failure mode that returns success:false without an error string, making the workflow surface the fallback message.

Common situations: Workflow templates referencing agent ids from a previous session (agent store is gone); API key rotated or expired between workflow runs; Ollama not running locally; agents terminated by a lifecycle cleanup while the workflow was still executing.

Related errors


AI-assisted analysis of ruvnet/ruflo@fa13ee4ad6 (2026-08-18). Data as JSON: /api/errors/b8725c91c027ecd8. Report an issue: GitHub.