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
- Run the enclosing test and read the inner Err to see why tool_search execution failed (cargo test -p codewhale-tui <test_name> -- --nocapture).
- Verify the surface's deferred catalog still contains the tool_search tool and that TOOL_SEARCH_NAME matches its registered name.
- Check the regex "match" mode path for changes; try the literal match mode to isolate the regex handling.
- If forked-context handling was refactored, confirm the child surface inherits the search tool after fork.
Example fix
// before
.execute_surface_tool(®istry, &mut surface, TOOL_SEARCH_NAME, json!({"query":"web","match":"regex"})).await.unwrap();
// after
let res = execute_surface_tool(®istry, &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(®istry, &mut surface, TOOL_SEARCH_NAME, &args).await;
if let Err(e) = res { panic!("tool_search failed: {e}"); } Prevention
- Keep TOOL_SEARCH_NAME in sync with the registered catalog name via a shared constant.
- After refactoring surface forking, run the subagent discovery tests with --nocapture.
- Add a startup assertion that every child surface retains tool_search.
- Avoid hard-coding regex queries in tests that depend on tool description text.
When it happens
Trigger: Calling execute_surface_tool(®istry, &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
- new child-local discovery
- search remains available
- Agent continuation target is no longer retained
- Agent continuation target is outside the active session
- Agent not found
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(
®istry,
&mut surface,
TOOL_SEARCH_NAME,
json!({"query": "web", "match": "regex"}),
)
.await
.expect("fresh discovery despite forked context");
execute_surface_tool(
®istry,
&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)