Hmbown/CodeWhale · error

ninth deferred child tool

Error message

ninth deferred child tool

What it means

A `.expect("ninth deferred child tool")` panic on Option: others.next() returned None, meaning the catalog contained fewer than nine deferred tools (one get_goal fixture plus the deferred set). The LRU cap test needs at least 9 deferred child tools; the catalog only supplied 8 or fewer.

Solutions

  1. Count the deferred entries in the Builder catalog to see how many exist and which are missing.
  2. Add another synthetic_deferred_tool fixture so at least nine deferred tools exist, or lower the test's expectation to the new cap.
  3. Check whether defer_loading defaults changed so formerly deferred tools are now eager.
  4. Confirm the filter (defer_loading == Some(true) && name != "get_goal") matches the intended fixture set.
Defensive patterns

Strategy: validation

Validate before calling

let deferred: Vec<&Tool> = catalog.iter().filter(|t| t.defer_loading == Some(true) && t.name != "get_goal").collect();
assert!(deferred.len() >= 8, "need 8+ deferred tools beyond get_goal, found {}", deferred.len());

Try / catch

let Some(ninth) = others.next() else {
    panic!("expected a ninth deferred tool; catalog has {} deferred", counted);
};

Prevention

When it happens

Trigger: After reserving "get_goal" and taking 7 others (warm.extend(others.by_ref().take(7))), the next others.next() at crates/tui/src/tools/subagent/tests.rs:8115 finds no ninth tool with defer_loading == Some(true) and name != "get_goal".

Common situations: A catalog change reduced the number of deferable child tools below nine; a tool's defer_loading default flipped to false; synthetic deferred fixtures were removed or renamed so they no longer carry defer_loading = Some(true).

Understand the failure class

Background: "Not found" and "does not exist" errors: why "Task not found", "No such folder", and "Can't find" fire when a lookup comes back empty — this error's family across 14 libraries.

Related errors


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

Appendix: source

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

#[tokio::test]
async fn small_surface_successful_cached_use_touches_lru() {
    let registry = small_surface_registry(FleetRole::Builder);
    let mut catalog = registry.deferred_catalog_for_model(&FleetRole::Builder);
    // Exercise the LRU with a deliberately deferred read-only fixture tool;
    // 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(&registry, &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,

View on GitHub (pinned to 73e0f67d83)