tinyhumansai/openhuman · warning

Missing 'agent' parameter

Error message

Missing 'agent' parameter

What it means

The `delegate` agent tool was invoked without a usable `agent` argument: args["agent"] is absent or not a JSON string (delegate.rs:126). The tool's JSON schema marks agent and prompt required, and the available agent ids are enumerated in the parameter description, so this is a malformed tool call. The empty-after-trim case is handled separately as a soft ToolResult::error, not this anyhow error.

Source

Thrown at src/openhuman/agent/tools/delegate.rs:126

                    "type": "string",
                    "minLength": 1,
                    "description": "The task/prompt to send to the sub-agent"
                },
                "context": {
                    "type": "string",
                    "description": "Optional context to prepend (e.g. relevant code, prior findings)"
                }
            },
            "required": ["agent", "prompt"]
        })
    }

    async fn execute(&self, args: serde_json::Value) -> anyhow::Result<ToolResult> {
        let agent_name = args
            .get("agent")
            .and_then(|v| v.as_str())
            .map(str::trim)
            .ok_or_else(|| anyhow::anyhow!("Missing 'agent' parameter"))?;

        if agent_name.is_empty() {
            return Ok(ToolResult::error("'agent' parameter must not be empty"));
        }

        let prompt = args
            .get("prompt")
            .and_then(|v| v.as_str())
            .map(str::trim)
            .ok_or_else(|| anyhow::anyhow!("Missing 'prompt' parameter"))?;

        if prompt.is_empty() {
            return Ok(ToolResult::error("'prompt' parameter must not be empty"));
        }

        let context = args
            .get("context")
            .and_then(|v| v.as_str())

View on GitHub (pinned to a221052e0d)

Solutions

  1. Pass "agent" as a non-empty string, one of the ids listed in the tool's parameter description
  2. Align the caller's arg keys with the schema (agent, prompt, optional context)
  3. Validate args against the tool's JSON schema before invoking if you wrap the tool
  4. Feed the error back to the model — it is self-correctable on retry

Example fix

// before
{ "prompt": "index the repo", "agent_name": "indexer" }

// after
{ "agent": "indexer", "prompt": "index the repo" }
Defensive patterns

Strategy: type-guard

Validate before calling

// Validate before invoking the delegate tool
function canCallDelegate(args: unknown): boolean {
  const a = args as Record<string, unknown>;
  return typeof a?.agent === "string" && (a.agent as string).trim() !== ""
      && typeof a?.prompt === "string" && (a.prompt as string).trim() !== "";
}

Type guard

function isDelegateArgs(a: unknown): a is { agent: string; prompt: string; context?: string } {
  if (typeof a !== "object" || a === null) return false;
  const v = a as Record<string, unknown>;
  return typeof v.agent === "string" && v.agent.trim() !== ""
      && typeof v.prompt === "string" && v.prompt.trim() !== ""
      && (v.context === undefined || typeof v.context === "string");
}

Try / catch

// In Rust wrappers: convert the anyhow error into model-visible tool feedback
if let Err(e) = tool.execute(args).await {
    if e.to_string().contains("Missing 'agent'") {
        return Ok(ToolResult::error("delegate requires 'agent' (see listed ids) and 'prompt'"));
    }
    return Err(e);
}

Prevention

When it happens

Trigger: LLM omits the agent field or passes null/number/object; a hand-rolled caller serializing args with a wrong key (agent_name instead of agent); schema drift between the advertised tool schema and the caller.

Common situations: Smaller models ignoring the required list; renamed parameters after tool-description edits; client code building args from unvalidated input.

Related errors


AI-assisted analysis of tinyhumansai/openhuman@a221052e0d (2026-08-16). Data as JSON: /api/errors/635881b1e9fc806e. Report an issue: GitHub.