{"record":{"id":"101a1f57fd4fc253","repo":"wavetermdev/waveterm","slug":"directory-listing-part-missing-data-101a1f","errorCode":null,"errorMessage":"directory listing part missing data","messagePattern":"directory listing part missing data","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/aiusechat/openai/openai-convertmessage.go","lineNumber":382,"sourceCode":"\t\t}, nil\n\n\tcase part.MimeType == \"text/plain\":\n\t\ttextData, err := aiutil.ExtractTextData(part.Data, part.URL)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tformattedText := aiutil.FormatAttachedTextFile(part.FileName, textData)\n\t\treturn &OpenAIMessageContent{\n\t\t\tType: \"input_text\",\n\t\t\tText: formattedText,\n\t\t}, nil\n\tcase part.MimeType == \"directory\":\n\t\tvar jsonContent string\n\n\t\tif len(part.Data) > 0 {\n\t\t\tjsonContent = string(part.Data)\n\t\t} else {\n\t\t\treturn nil, fmt.Errorf(\"directory listing part missing data\")\n\t\t}\n\n\t\tformattedText := aiutil.FormatAttachedDirectoryListing(part.FileName, jsonContent)\n\n\t\treturn &OpenAIMessageContent{\n\t\t\tType: \"input_text\",\n\t\t\tText: formattedText,\n\t\t}, nil\n\n\tdefault:\n\t\treturn nil, fmt.Errorf(\"dropping file with unsupported mimetype '%s' (OpenAI supports images, PDFs, text/plain, and directories)\", part.MimeType)\n\t}\n}\n\n// ConvertAIMessageToOpenAIChatMessage converts an AIMessage to OpenAIChatMessage\n// These messages are ALWAYS role \"user\"\n// Handles text parts, images, PDFs, and text/plain files\nfunc ConvertAIMessageToOpenAIChatMessage(aiMsg uctypes.AIMessage) (*OpenAIChatMessage, error) {","sourceCodeStart":364,"sourceCodeEnd":400,"githubUrl":"https://github.com/wavetermdev/waveterm/blob/a4447c1563b2df285ab89e76c82f91e1a1a49c1e/pkg/aiusechat/openai/openai-convertmessage.go#L364-L400","documentation":"Validation error: a directory-listing file part in an OpenAI message conversion is missing its data payload (the serialized listing).","triggerScenarios":"Adding a directory part without generating the listing JSON into Data; the directory snapshot step was skipped or failed; part constructed from metadata only (FileName set, Data empty).","commonSituations":"Custom tooling that attaches directory context to chats but doesn't serialize the listing; races where the directory read produced no output; refactors that dropped the listing-generation step.","solutions":["Populate part.Data with the directory listing serialized as JSON before sending","Run your directory-listing generation (e.g. lsjson output) and marshal it into Data","Validate directory parts contain non-empty Data in a pre-send check"],"exampleFix":"// before\npart := uctypes.AIMessagePart{Type: \"file\", MimeType: \"directory\", FileName: \"project/src\"}\n// after\nlisting, _ := json.Marshal(dirEntries)\npart := uctypes.AIMessagePart{Type: \"file\", MimeType: \"directory\", FileName: \"project/src\", Data: listing}","handlingStrategy":"validation","validationCode":"func ensureDirectoryData(p uctypes.AIMessagePart) error {\n    if p.MimeType == \"directory\" && len(p.Data) == 0 {\n        return errors.New(\"directory listing part has no JSON data\")\n    }\n    return nil\n}","typeGuard":"func hasDirectoryData(p uctypes.AIMessagePart) bool {\n    return p.MimeType == \"directory\" && len(p.Data) > 0\n}","tryCatchPattern":null,"preventionTips":["Generate and marshal the directory listing into Data at attach time","Skip empty listings rather than attaching empty parts","Validate all parts before sending"],"tags":["openai","directory-listing","message-conversion","missing-data"],"backgroundTag":"attachment-data-missing","analyzedSha":"a4447c1563b2df285ab89e76c82f91e1a1a49c1e","analyzedAt":"2026-09-01T15:26:23.972Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}