Hmbown/CodeWhale · error
search remains available
Error message
search remains available
What it means
A `.expect("search remains available")` panic: the tool_search tool failed to execute when the test verifies it stays reachable after other tools are evicted/deferred. tool_search is supposed to remain hydrated at all times so the model can rediscover deferred tools; its failure breaks that guarantee.
Solutions
- Inspect the Err from the failing call to see whether the tool is missing or execution failed.
- Ensure tool_search is always kept eager/warm and never counted against the deferred cache cap.
- Re-run with the warm list including TOOL_SEARCH_NAME to confirm eviction is the cause.
- Check that surface.hydrate("Web") failing afterwards is intended and unrelated to search availability.
Defensive patterns
Strategy: validation
Validate before calling
// Before executing, ensure tool_search is warm/eager on the surface let warm = surface.warm_names(); assert!(warm.iter().any(|n| n == TOOL_SEARCH_NAME), "tool_search was evicted or never warmed");
Try / catch
if let Err(e) = execute_surface_tool(®istry, &mut surface, TOOL_SEARCH_NAME, &args).await {
panic!("search must remain available after eviction changes: {e}");
} Prevention
- Exclude tool_search from the deferred LRU cap accounting by construction, not by test.
- Add an invariant check that hydration never evicts tool_search.
- Keep warm lists derived from constants rather than positional filters.
- Re-run eviction tests whenever the deferred cache cap changes.
When it happens
Trigger: execute_surface_tool(®istry, &mut surface, TOOL_SEARCH_NAME, json!({"query":"web","match":"regex"})) returns Err in crates/tui/src/tools/subagent/tests.rs:8031, typically because the surface treated tool_search as deferable and evicted it, or its execution errored after hydration changes.
Common situations: Tightening the deferred-tool LRU so tool_search itself is evicted; changing SubAgentToolSurface::new to warm only a fixed list that omits tool_search; renaming TOOL_SEARCH_NAME.
Related errors
- cached read tool executes
- fresh discovery despite forked context
- new child-local discovery
- ninth activation
- ninth deferred child tool
AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22).
Data as JSON: /api/errors/d07daae4d295c257.
Report an issue: GitHub.
Appendix: source
Thrown at crates/tui/src/tools/subagent/tests.rs:8031
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(),
);
let catalog = registry.deferred_catalog_for_model(&FleetRole::Scout);
let mut surface = SubAgentToolSurface::new(catalog, &["Web".to_string()]);
assert!(!model_tool_names(model_request_tools(&mut surface)).contains("Web"));
let searched = execute_surface_tool(
®istry,
&mut surface,
TOOL_SEARCH_NAME,
json!({"query": "web", "match": "regex"}),
)
.await
.expect("search remains available");
assert!(!searched.contains("\"tool_name\":\"Web\""));
assert!(surface.hydrate("Web").is_err());
}
fn synthetic_deferred_tool(name: &str, description_bytes: usize) -> Tool {
Tool {
tool_type: Some("function".to_string()),
name: name.to_string(),
description: "x".repeat(description_bytes),
input_schema: json!({"type": "object", "properties": {}}),
allowed_callers: None,
defer_loading: Some(true),
input_examples: None,
strict: None,
cache_control: None,
}
}
View on GitHub (pinned to 73e0f67d83)