Hmbown/CodeWhale · error
ninth activation
Error message
ninth activation
What it means
A `.expect("ninth activation")` panic: surface.hydrate(&ninth) returned Err when the test tries to hydrate the ninth deferred tool, expecting the LRU to evict another entry to admit it. Failure means the hydration path rejects the activation instead of evicting a cached slot.
Solutions
- Inspect the Err from hydrate: a not-found error points at the fixture list, a cache error at eviction policy.
- Verify the ninth tool's name exists in the catalog (print catalog names before hydrate).
- Confirm the LRU evicts the least-recently-used entry when a tenth tool is hydrated at the cap of nine.
- Re-check that get_goal stayed hydrated after eviction if the test asserts on it afterwards.
Defensive patterns
Strategy: try-catch
Validate before calling
assert!(catalog.iter().any(|t| t.name == *ninth), "ninth tool '{}' not in catalog", ninth); Type guard
fn in_catalog(catalog: &[Tool], name: &str) -> bool { catalog.iter().any(|t| t.name == name) } Try / catch
surface.hydrate(&ninth).unwrap_or_else(|e| panic!("hydrating '{}' failed: {e}", ninth)); Prevention
- Verify the ninth fixture exists in the catalog before the hydration step.
- Keep the LRU eviction-on-hydrate contract covered by an explicit unit test.
- Make hydrate errors carry the missing tool name.
- Re-check cap-dependent tests whenever eviction policy changes.
When it happens
Trigger: surface.hydrate(&ninth) at crates/tui/src/tools/subagent/tests.rs:8121 errors — typically a not-found error because the ninth name is not in the catalog, or a cache-full error because the LRU no longer evicts on hydration at the cap.
Common situations: The catalog actually had fewer than nine deferred tools so `ninth` is an empty/garbage name; an LRU policy change made hydration at cap fail hard instead of evicting; hydrate now requires exact-name matching that the fixture name fails.
Understand the failure class
Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.
Related errors
- ninth deferred child tool
- cached read tool executes
- search remains available
- continue_goal with a wire-supplied schedule id still parses
- expected exec command
AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22).
Data as JSON: /api/errors/66a8920a2c375aee.
Report an issue: GitHub.
Appendix: source
Thrown at crates/tui/src/tools/subagent/tests.rs:8121
// production goal controls are eager and must not consume cache slots.
catalog
.iter_mut()
.find(|tool| tool.name == "get_goal")
.expect("goal read fixture")
.defer_loading = Some(true);
let mut others = catalog
.iter()
.filter(|tool| tool.defer_loading == Some(true) && tool.name != "get_goal")
.map(|tool| tool.name.clone());
let mut warm = vec!["get_goal".to_string()];
warm.extend(others.by_ref().take(7));
let ninth = others.next().expect("ninth deferred child tool");
let mut surface = SubAgentToolSurface::new(catalog, &warm);
model_request_tools(&mut surface);
execute_surface_tool(®istry, &mut surface, "get_goal", json!({}))
.await
.expect("cached read tool executes");
surface.hydrate(&ninth).expect("ninth activation");
assert!(model_tool_names(model_request_tools(&mut surface)).contains("get_goal"));
}
#[test]
fn small_surface_depth_cap_removes_only_agent() {
let mut runtime =
stub_runtime().with_agent_tool_surface_options(enabled_agent_surface_options());
runtime.worker_profile = WorkerRuntimeProfile::for_role(FleetRole::Builder);
runtime.spawn_depth = runtime.max_spawn_depth;
let registry = SubAgentToolRegistry::new(
runtime,
FleetRole::Builder,
None,
crate::tools::todo::new_shared_todo_list(),
crate::tools::plan::new_shared_plan_state(),
);
let mut surface = SubAgentToolSurface::new(
registry.deferred_catalog_for_model(&FleetRole::Builder),View on GitHub (pinned to 73e0f67d83)