{"record":{"id":"5abef822cef85fb8","repo":"Hmbown/CodeWhale","slug":"fresh-discovery-despite-forked-context","errorCode":null,"errorMessage":"fresh discovery despite forked context","messagePattern":"fresh discovery despite forked context","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/tui/src/tools/subagent/tests.rs","lineNumber":7994,"sourceCode":"            .contains(\"continue from parent\")\n    );\n    assert_eq!(\n        context.messages, original_messages,\n        \"child request setup must not mutate the captured parent context\"\n    );\n\n    // A parent tool-search result is transcript context, not inherited tool\n    // authority. The child starts from its own filtered catalog/cache and can\n    // independently discover Web plus a tool the parent never searched for.\n    assert!(!model_tool_names(model_request_tools(&mut surface)).contains(\"Web\"));\n    execute_surface_tool(\n        &registry,\n        &mut surface,\n        TOOL_SEARCH_NAME,\n        json!({\"query\": \"web\", \"match\": \"regex\"}),\n    )\n    .await\n    .expect(\"fresh discovery despite forked context\");\n    execute_surface_tool(\n        &registry,\n        &mut surface,\n        TOOL_SEARCH_NAME,\n        json!({\"query\": \"apply_patch\", \"match\": \"regex\"}),\n    )\n    .await\n    .expect(\"new child-local discovery\");\n    let names = model_tool_names(model_request_tools(&mut surface));\n    assert!(names.contains(\"Web\"));\n    assert!(names.contains(\"apply_patch\"));\n}\n\n#[tokio::test]\nasync fn small_surface_denied_warm_tool_is_not_resurrected() {\n    let mut runtime =\n        stub_runtime().with_agent_tool_surface_options(enabled_agent_surface_options());\n    runtime.worker_profile = WorkerRuntimeProfile::for_role(FleetRole::Scout);","sourceCodeStart":7976,"sourceCodeEnd":8012,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/73e0f67d83c59909b571efdfc88c4bc28c309cb1/crates/tui/src/tools/subagent/tests.rs#L7976-L8012","documentation":"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.","triggerScenarios":"Calling execute_surface_tool(&registry, &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.","commonSituations":"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.","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."],"exampleFix":"// before\n.execute_surface_tool(&registry, &mut surface, TOOL_SEARCH_NAME, json!({\"query\":\"web\",\"match\":\"regex\"})).await.unwrap();\n// after\nlet res = execute_surface_tool(&registry, &mut surface, TOOL_SEARCH_NAME, json!({\"query\":\"web\",\"match\":\"regex\"})).await.expect(\"tool_search should execute on forked surface: {res:?}\");","handlingStrategy":"try-catch","validationCode":"// Rust: assert the tool exists before executing\nassert!(registry.deferred_catalog_for_model(&role).iter().any(|t| t.name == TOOL_SEARCH_NAME), \"tool_search missing from catalog\");","typeGuard":"fn has_tool(catalog: &[Tool], name: &str) -> bool { catalog.iter().any(|t| t.name == name) }","tryCatchPattern":"// Unwrap with context instead of bare expect\nlet res = execute_surface_tool(&registry, &mut surface, TOOL_SEARCH_NAME, &args).await;\nif let Err(e) = res { panic!(\"tool_search failed: {e}\"); }","preventionTips":["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."],"tags":["rust","test-panic","tool-search","subagent"],"backgroundTag":"tool-execution-failed","analyzedSha":"73e0f67d83c59909b571efdfc88c4bc28c309cb1","analyzedAt":"2026-09-22T01:30:00.501Z","contentChangedAt":"2026-09-22T01:30:00.501Z","schemaVersion":2},"datasetVersion":"2026-09-22T11:17:16.035Z"}