Hmbown/CodeWhale · error

fresh discovery despite forked context

Error message

fresh discovery despite forked context

What it means

This is a Rust test panic: `.expect("fresh discovery despite forked context")` unwraps the Result of executing the tool_search tool inside a sub-agent surface. The test library (std) panics with the message when the tool call returns Err or the surface fails to execute tool_search. It signals that tool discovery via regex query stopped working after a forked context was set up in the test harness.

Solutions

  1. Run the enclosing test and read the inner Err to see why tool_search execution failed (cargo test -p codewhale-tui <test_name> -- --nocapture).
  2. Verify the surface's deferred catalog still contains the tool_search tool and that TOOL_SEARCH_NAME matches its registered name.
  3. Check the regex "match" mode path for changes; try the literal match mode to isolate the regex handling.
  4. If forked-context handling was refactored, confirm the child surface inherits the search tool after fork.

Example fix

// before
.execute_surface_tool(&registry, &mut surface, TOOL_SEARCH_NAME, json!({"query":"web","match":"regex"})).await.unwrap();
// after
let res = execute_surface_tool(&registry, &mut surface, TOOL_SEARCH_NAME, json!({"query":"web","match":"regex"})).await.expect("tool_search should execute on forked surface: {res:?}");
Defensive patterns

Strategy: try-catch

Validate before calling

// Rust: assert the tool exists before executing
assert!(registry.deferred_catalog_for_model(&role).iter().any(|t| t.name == TOOL_SEARCH_NAME), "tool_search missing from catalog");

Type guard

fn has_tool(catalog: &[Tool], name: &str) -> bool { catalog.iter().any(|t| t.name == name) }

Try / catch

// Unwrap with context instead of bare expect
let res = execute_surface_tool(&registry, &mut surface, TOOL_SEARCH_NAME, &args).await;
if let Err(e) = res { panic!("tool_search failed: {e}"); }

Prevention

When it happens

Trigger: Calling execute_surface_tool(&registry, &mut surface, TOOL_SEARCH_NAME, json!({"query":"web","match":"regex"})) in crates/tui/src/tools/subagent/tests.rs returns Err — e.g. tool_search is not registered in the surface's catalog, the regex match mode is rejected, or forked-context bookkeeping dropped the search tool.

Common situations: Renaming TOOL_SEARCH_NAME or the tool catalog while tests still reference the old name; changing SubAgentToolSurface to filter tool_search out of child surfaces; a regex engine change making the "regex" match mode error on this query; breaking tool hydration/forking so the surface has no tools left.

Related errors


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

Appendix: source

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

            .contains("continue from parent")
    );
    assert_eq!(
        context.messages, original_messages,
        "child request setup must not mutate the captured parent context"
    );

    // A parent tool-search result is transcript context, not inherited tool
    // authority. The child starts from its own filtered catalog/cache and can
    // independently discover Web plus a tool the parent never searched for.
    assert!(!model_tool_names(model_request_tools(&mut surface)).contains("Web"));
    execute_surface_tool(
        &registry,
        &mut surface,
        TOOL_SEARCH_NAME,
        json!({"query": "web", "match": "regex"}),
    )
    .await
    .expect("fresh discovery despite forked context");
    execute_surface_tool(
        &registry,
        &mut surface,
        TOOL_SEARCH_NAME,
        json!({"query": "apply_patch", "match": "regex"}),
    )
    .await
    .expect("new child-local discovery");
    let names = model_tool_names(model_request_tools(&mut surface));
    assert!(names.contains("Web"));
    assert!(names.contains("apply_patch"));
}

#[tokio::test]
async fn small_surface_denied_warm_tool_is_not_resurrected() {
    let mut runtime =
        stub_runtime().with_agent_tool_surface_options(enabled_agent_surface_options());
    runtime.worker_profile = WorkerRuntimeProfile::for_role(FleetRole::Scout);

View on GitHub (pinned to 73e0f67d83)