@@ -391,6 +391,21 @@ fn parse_cli_json(text: &str) -> Result<Value, ProviderError> {
391391
392392fn parse_claude_json ( text : & str ) -> Result < Value , ProviderError > {
393393 let outer = parse_cli_json ( text) ?;
394+ if let Some ( structured_output) = outer. get ( "structured_output" ) {
395+ if structured_output. is_object ( ) {
396+ return Ok ( structured_output. clone ( ) ) ;
397+ }
398+
399+ return Err ( ProviderError :: invalid_provider_response (
400+ "Claude CLI structured_output field was not a JSON object" ,
401+ Some ( json ! ( {
402+ "field" : "structured_output" ,
403+ "value" : structured_output. clone( ) ,
404+ "outer" : outer. clone( ) ,
405+ } ) ) ,
406+ ) ) ;
407+ }
408+
394409 if let Some ( result) = outer. get ( "result" ) {
395410 if let Some ( result_text) = result. as_str ( ) {
396411 return parse_cli_json ( result_text) ;
@@ -722,4 +737,40 @@ mod tests {
722737
723738 assert_eq ! ( parsed[ "summary" ] , "ok" ) ;
724739 }
740+
741+ #[ test]
742+ fn claude_structured_output_field_is_preferred ( ) {
743+ let parsed = parse_claude_json (
744+ r#"{"result":"","structured_output":{"roles":[{"canonical_key":"http_route_handler"}]}}"# ,
745+ )
746+ . expect ( "claude structured output" ) ;
747+
748+ assert_eq ! ( parsed[ "roles" ] [ 0 ] [ "canonical_key" ] , "http_route_handler" ) ;
749+ }
750+
751+ #[ test]
752+ fn claude_structured_output_wins_over_prose_result ( ) {
753+ let parsed = parse_claude_json (
754+ r#"{"result":"I've inferred roles...","structured_output":{"roles":[]}}"# ,
755+ )
756+ . expect ( "claude structured output" ) ;
757+
758+ assert_eq ! ( parsed[ "roles" ] . as_array( ) . unwrap( ) . len( ) , 0 ) ;
759+ }
760+
761+ #[ test]
762+ fn claude_structured_output_must_be_object ( ) {
763+ let error = parse_claude_json ( r#"{"result":"{}","structured_output":"not-object"}"# )
764+ . expect_err ( "non-object structured output should fail" ) ;
765+
766+ assert_eq ! ( error. code, "invalid_provider_response" ) ;
767+ assert ! (
768+ error. message. contains( "structured_output" ) ,
769+ "error should identify the malformed structured_output field: {}" ,
770+ error. message
771+ ) ;
772+ let details = error. details . expect ( "details" ) ;
773+ assert_eq ! ( details[ "field" ] , "structured_output" ) ;
774+ assert_eq ! ( details[ "value" ] , "not-object" ) ;
775+ }
725776}
0 commit comments