Hmbown/CodeWhale · error
goal read fixture
Error message
goal read fixture
What it means
A `.expect("goal read fixture")` panic on Option: catalog.iter_mut().find(|tool| tool.name == "get_goal") returned None. The test needs a read-only goal tool fixture to exercise the deferred LRU, and the model catalog for FleetRole::Builder no longer contains a tool named get_goal.
Solutions
- Print/inspect the catalog names to confirm the tool's current name (e.g. debug-list all tool.name values).
- Update the test fixture to the tool's new name, or restore "get_goal" to the Builder catalog.
- Check whether the goal tool moved from deferred to eager; if it is now eager this test needs a different read-only fixture.
- Verify deferred_catalog_for_model(&FleetRole::Builder) is the right role for this fixture.
Example fix
// before
.find(|tool| tool.name == "get_goal")
.expect("goal read fixture")
// after
.find(|tool| tool.name == "get_goal" || tool.name == "goal_read")
.expect("goal read fixture (catalog: {:?})") Defensive patterns
Strategy: type-guard
Validate before calling
let goal = catalog.iter_mut().find(|t| t.name == "get_goal");
assert!(goal.is_some(), "get_goal absent from Builder catalog: {:?}", catalog.iter().map(|t| &t.name).collect::<Vec<_>>()); Type guard
fn find_tool<'a>(catalog: &'a mut [Tool], name: &str) -> Option<&'a mut Tool> {
catalog.iter_mut().find(|t| t.name == name)
} Try / catch
let Some(tool) = find_tool(&mut catalog, "get_goal") else {
panic!("goal read fixture missing; available: {:?}", names(&catalog));
}; Prevention
- Reference fixture tools by exported constants, not inline string literals.
- When renaming a tool, grep the test suite for its old name.
- Assert on the catalog's name list in the panic message to speed diagnosis.
- Keep at least one known read-only fixture per role's catalog.
When it happens
Trigger: registry.deferred_catalog_for_model(&FleetRole::Builder) in crates/tui/src/tools/subagent/tests.rs:8107 yields a catalog without "get_goal" — the goal tool was renamed, made eager (defer_loading removed), or filtered out of the Builder role's catalog.
Common situations: Renaming get_goal in the goal tool module; changing FleetRole catalogs so Builder no longer exposes the read-only goal tool; a fixture setup change that excludes goal tools.
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
- ninth deferred child tool
- cached read tool executes
- Concentrate catalog delta
- continue_goal with a wire-supplied schedule id still parses
- default row
AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22).
Data as JSON: /api/errors/121cf9e46bc0d021.
Report an issue: GitHub.
Appendix: source
Thrown at crates/tui/src/tools/subagent/tests.rs:8107
let byte_warm = (0..3)
.map(|index| format!("bytes_{index}"))
.collect::<Vec<_>>();
let mut byte_surface = SubAgentToolSurface::new(byte_catalog, &byte_warm);
let byte_names = model_tool_names(model_request_tools(&mut byte_surface));
assert!(!byte_names.contains("bytes_0"));
assert!(byte_names.contains("bytes_1") && byte_names.contains("bytes_2"));
}
#[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(®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]View on GitHub (pinned to 73e0f67d83)