wavetermdev/waveterm · error

directory listing part missing data

Error message

directory listing part missing data

What it means

Validation error: a directory-listing file part in an OpenAI message conversion is missing its data payload (the serialized listing).

Solutions

  1. Populate part.Data with the directory listing serialized as JSON before sending
  2. Run your directory-listing generation (e.g. lsjson output) and marshal it into Data
  3. Validate directory parts contain non-empty Data in a pre-send check

Example fix

// before
part := uctypes.AIMessagePart{Type: "file", MimeType: "directory", FileName: "project/src"}
// after
listing, _ := json.Marshal(dirEntries)
part := uctypes.AIMessagePart{Type: "file", MimeType: "directory", FileName: "project/src", Data: listing}
Defensive patterns

Strategy: validation

Validate before calling

func ensureDirectoryData(p uctypes.AIMessagePart) error {
    if p.MimeType == "directory" && len(p.Data) == 0 {
        return errors.New("directory listing part has no JSON data")
    }
    return nil
}

Type guard

func hasDirectoryData(p uctypes.AIMessagePart) bool {
    return p.MimeType == "directory" && len(p.Data) > 0
}

Prevention

When it happens

Trigger: 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).

Common situations: 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.

Related errors


AI-assisted analysis of wavetermdev/waveterm@a4447c1563 (2026-09-01). Data as JSON: /api/errors/101a1f57fd4fc253. Report an issue: GitHub.

Appendix: source

Thrown at pkg/aiusechat/openai/openai-convertmessage.go:382

		}, nil

	case part.MimeType == "text/plain":
		textData, err := aiutil.ExtractTextData(part.Data, part.URL)
		if err != nil {
			return nil, err
		}
		formattedText := aiutil.FormatAttachedTextFile(part.FileName, textData)
		return &OpenAIMessageContent{
			Type: "input_text",
			Text: formattedText,
		}, nil
	case part.MimeType == "directory":
		var jsonContent string

		if len(part.Data) > 0 {
			jsonContent = string(part.Data)
		} else {
			return nil, fmt.Errorf("directory listing part missing data")
		}

		formattedText := aiutil.FormatAttachedDirectoryListing(part.FileName, jsonContent)

		return &OpenAIMessageContent{
			Type: "input_text",
			Text: formattedText,
		}, nil

	default:
		return nil, fmt.Errorf("dropping file with unsupported mimetype '%s' (OpenAI supports images, PDFs, text/plain, and directories)", part.MimeType)
	}
}

// ConvertAIMessageToOpenAIChatMessage converts an AIMessage to OpenAIChatMessage
// These messages are ALWAYS role "user"
// Handles text parts, images, PDFs, and text/plain files
func ConvertAIMessageToOpenAIChatMessage(aiMsg uctypes.AIMessage) (*OpenAIChatMessage, error) {

View on GitHub (pinned to a4447c1563)