Hmbown/CodeWhale · error

same-batch first use hydrates instead of executing

Error message

same-batch first use hydrates instead of executing

What it means

A panic from `.expect("same-batch first use hydrates instead of executing")` in the deferred-tools test. It executes a first direct use of the deferred `Web` tool within the same request batch and asserts that the registry hydrates the tool into the request surface (returns a "deferred" notice) rather than executing it; an `Err` from `execute_from_surface`, or a content mismatch afterwards, panics here. It pins the hydration-before-execution contract for first-use of deferred tools.

Solutions

  1. Inspect the `Err` (swap `.expect` for a `panic!("...: {e:?}")` wrapper) to identify whether execution or argument validation failed
  2. Check `surface.active_names` before the call — if Web was already hydrated by the preceding tool_search batch, the test's premise changed and the fixture needs a fresh surface
  3. If the contract changed intentionally (first use now executes), update the assertion content and test name; otherwise restore hydration-on-first-use in the registry

Example fix

// before
.await
.expect("same-batch first use hydrates instead of executing");
// after (diagnose)
.await
.unwrap_or_else(|e| panic!("same-batch hydration failed: {e:?}"));
Defensive patterns

Strategy: try-catch

Validate before calling

assert!(!surface.active_names.contains(&"Web".to_string()),
    "Web already active; first-use hydration path cannot be exercised");

Try / catch

let same_batch = registry.execute_from_surface(...).await
    .unwrap_or_else(|e| panic!("same-batch first use failed: {e:?}"));

Prevention

When it happens

Trigger: `execute_from_surface` for `Web` with `{action: "search", query: "codewhale"}` returns `Err` — Web was already hydrated (state drift from the earlier tool_search call), the tool is missing from the deferred catalog, or the arguments fail validation — or the result content no longer contains "deferred".

Common situations: A change in hydration semantics (executing instead of hydrating) breaks the contract; earlier test steps left the surface in a hydrated state; argument schema for the Web tool changed.

Understand the failure class

Background: "API request failed": what wrapped HTTP errors from external APIs mean and how to find the real cause — this error's family across 29 libraries.

Related errors


AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22). Data as JSON: /api/errors/e3880524a13aa391. Report an issue: GitHub.

Appendix: source

Thrown at crates/tui/src/tools/subagent/tests.rs:7929

            &mut surface,
            &request_active,
            TOOL_SEARCH_NAME,
            json!({"query": "web", "match": "regex"}),
        )
        .await
        .expect("child-local search");
    assert!(result.result.content.contains("\"tool_name\":\"Web\""));
    let same_batch = registry
        .execute_from_surface(
            "agent_scout",
            "",
            &mut surface,
            &request_active,
            "Web",
            json!({"action": "search", "query": "codewhale"}),
        )
        .await
        .expect("same-batch first use hydrates instead of executing");
    assert!(same_batch.result.content.contains("deferred"));
    assert!(model_tool_names(model_request_tools(&mut surface)).contains("Web"));
}

#[tokio::test]
async fn small_surface_fork_context_survives_fresh_child_discovery() {
    let registry = small_surface_registry(FleetRole::Builder);
    let context = SubAgentForkContext {
        messages: vec![
            Message {
                role: Role::Assistant,
                content: vec![ContentBlock::ToolUse {
                    id: "search-1".to_string(),
                    name: TOOL_SEARCH_NAME.to_string(),
                    input: json!({"query": "web"}),
                    caller: None,
                    thought_signature: None,
                }],

View on GitHub (pinned to 73e0f67d83)