{"record":{"id":"18f6229048ed7498","repo":"wavetermdev/waveterm","slug":"failed-to-marshal-error-output-w","errorCode":null,"errorMessage":"failed to marshal error output: %w","messagePattern":"failed to marshal error output: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/aiusechat/openai/openai-convertmessage.go","lineNumber":480,"sourceCode":"\n\tvar messages []*OpenAIChatMessage\n\n\tfor _, result := range toolResults {\n\t\tif result.ToolUseID == \"\" {\n\t\t\treturn nil, fmt.Errorf(\"tool result missing ToolUseID\")\n\t\t}\n\n\t\t// Create the function call output with result data\n\t\tvar outputData any\n\t\tif result.ErrorText != \"\" {\n\t\t\t// Marshal error output to string\n\t\t\terrorOutput := OpenAIFunctionCallErrorOutput{\n\t\t\t\tOk:    \"false\",\n\t\t\t\tError: result.ErrorText,\n\t\t\t}\n\t\t\terrorBytes, err := json.Marshal(errorOutput)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"failed to marshal error output: %w\", err)\n\t\t\t}\n\t\t\toutputData = string(errorBytes)\n\t\t} else {\n\t\t\t// Check if text looks like an image data URL\n\t\t\tif strings.HasPrefix(result.Text, \"data:image/\") {\n\t\t\t\t// Convert to output array with input_image type\n\t\t\t\toutputData = []OpenAIMessageContent{\n\t\t\t\t\t{\n\t\t\t\t\t\tType:     \"input_image\",\n\t\t\t\t\t\tImageUrl: result.Text,\n\t\t\t\t\t},\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// Use text result for success\n\t\t\t\toutputData = result.Text\n\t\t\t}\n\t\t}\n","sourceCodeStart":462,"sourceCodeEnd":498,"githubUrl":"https://github.com/wavetermdev/waveterm/blob/a4447c1563b2df285ab89e76c82f91e1a1a49c1e/pkg/aiusechat/openai/openai-convertmessage.go#L462-L498","documentation":"When a tool result carries an error (ErrorText != \"\"), the converter builds an OpenAIFunctionCallErrorOutput and JSON-marshals it; a marshal failure (practically impossible for this fixed struct, but defensively handled) aborts conversion wrapped with this message.","triggerScenarios":"ConvertToolResultsToOpenAIChatMessage hits the ErrorText branch and json.Marshal of OpenAIFunctionCallErrorOutput returns an error — only possible if the struct gains fields that cannot be marshaled (e.g. channel/func values) in a modified build.","commonSituations":"Custom forks or locally patched versions of the struct with unmarshalable fields; otherwise this path is unreachable and indicates an unexpected internal failure.","solutions":["Verify ErrorText contains valid string data (it should be a plain string)","If you patched OpenAIFunctionCallErrorOutput, ensure all fields are JSON-marshalable","Update/restore the upstream library version if local modifications introduced the issue"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"if result.ErrorText != \"\" {\n    if _, err := json.Marshal(OpenAIFunctionCallErrorOutput{Ok: \"false\", Error: result.ErrorText}); err != nil {\n        return fmt.Errorf(\"unmarshalable error output: %w\", err)\n    }\n}","typeGuard":null,"tryCatchPattern":"out, err := ConvertToolResultsToOpenAIChatMessage(results)\nif err != nil && strings.Contains(err.Error(), \"failed to marshal error output\") {\n    // fall back to a plain-text error output\n}","preventionTips":["Keep OpenAIFunctionCallErrorOutput fields JSON-safe (strings only)","Avoid local modifications adding unmarshalable fields","Sanitize ErrorText to a plain string"],"tags":["json","openai","marshaling"],"backgroundTag":"json-marshal-failed","analyzedSha":"a4447c1563b2df285ab89e76c82f91e1a1a49c1e","analyzedAt":"2026-09-01T15:26:23.972Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}