Hmbown/CodeWhale · error

new child-local discovery

Error message

new child-local discovery

What it means

A `.expect("new child-local discovery")` panic: the tool_search call for query "apply_patch" with regex match failed inside a freshly created child-local SubAgentToolSurface. The test asserts that a child agent can independently discover tools; the panic means discovery returned Err rather than results.

Solutions

  1. Run the test with --nocapture and inspect the underlying Err from tool_search.
  2. Confirm the child-local catalog includes a tool named apply_patch and TOOL_SEARCH_NAME resolves.
  3. Verify the child surface is constructed with the same catalog the parent used (SubAgentToolSurface::new(catalog, ...)).
  4. Test the same query against the parent surface to isolate whether the child surface path is at fault.
Defensive patterns

Strategy: try-catch

Validate before calling

assert!(catalog.iter().any(|t| t.name == "apply_patch"), "apply_patch missing from child catalog");

Type guard

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

Try / catch

match execute_surface_tool(&registry, &mut surface, TOOL_SEARCH_NAME, &args).await {
    Ok(v) => v,
    Err(e) => panic!("child-local discovery failed: {e}"),
}

Prevention

When it happens

Trigger: execute_surface_tool(&registry, &mut surface, TOOL_SEARCH_NAME, json!({"query":"apply_patch","match":"regex"})) returns Err in crates/tui/src/tools/subagent/tests.rs:8002 — child catalog missing apply_patch, regex mode rejected, or surface not initialized with a catalog.

Common situations: Refactoring the child surface constructor so its catalog is empty; renaming apply_patch; changing tool_search query semantics so regex patterns no longer match tool descriptions.

Related errors


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

Appendix: source

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

    // 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);
    runtime.worker_profile.denied_tools.push("Web".to_string());
    let registry = SubAgentToolRegistry::new(
        runtime,
        FleetRole::Scout,
        None,
        crate::tools::todo::new_shared_todo_list(),
        crate::tools::plan::new_shared_plan_state(),
    );

View on GitHub (pinned to 73e0f67d83)