bytedance/deer-flow · error
Failed to prepare ${failedConversions} attachment(s) for upl
Error message
Failed to prepare ${failedConversions} attachment(s) for upload. Please retry. What it means
Thrown during message send when converting the prompt input's file parts to File objects via promptInputFilePartToFile. Each conversion returning null (unsupported or unreadable part) is counted, and any nonzero count aborts the send with this error before upload, asking the user to retry.
Source
Thrown at frontend/src/core/threads/hooks.ts:2139
let uploadedFileInfo: UploadedFileInfo[] = [];
try {
// Upload files first if any
if (message.files && message.files.length > 0) {
setIsUploading(true);
try {
const filePromises = message.files.map((fileUIPart) =>
promptInputFilePartToFile(fileUIPart),
);
const conversionResults = await Promise.all(filePromises);
const files = conversionResults.filter(
(file): file is File => file !== null,
);
const failedConversions = conversionResults.length - files.length;
if (failedConversions > 0) {
throw new Error(
`Failed to prepare ${failedConversions} attachment(s) for upload. Please retry.`,
);
}
if (!threadId) {
throw new Error("Thread is not ready for file upload.");
}
if (files.length > 0) {
const uploadResponse = await uploadFiles(threadId, files);
uploadedFileInfo = uploadResponse.files;
// Update optimistic human message with uploaded status + paths
const uploadedFiles: FileInMessage[] = uploadedFileInfo.map(
(info) => ({
filename: info.filename,
size: info.size,
path: info.virtual_path,View on GitHub (pinned to 1dd6ba1acb)
Solutions
- Reproduce with the same attachment and console.log the failing file part to see which kind/shape returns null.
- Re-attach the file (paste/drop again) — a corrupted in-memory part is often transient; hence the 'Please retry' wording.
- Extend promptInputFilePartToFile to handle the part kind, or normalize the editor to only emit supported kinds.
- Update the frontend to a consistent version so the input component and converter agree on part shapes.
Example fix
// before: unsupported part silently becomes null and aborts the whole send
const file = promptInputFilePartToFile(part); // null for {type: 'file', kind: 'reference'}
// after: convert reference parts via their stored path
function promptInputFilePartToFile(part) {
if (part.kind === 'reference' && part.path) { return referenceToFile(part.path); }
return legacyConverter(part);
} Defensive patterns
Strategy: validation
Validate before calling
const supported = message.files.every((p) => isConvertibleFilePart(p));
if (!supported) { /* disable send, show per-file error instead of aborting whole message */ } Type guard
function isConvertibleFilePart(part: unknown): boolean {
if (typeof part !== "object" || part === null) return false;
const kind = Reflect.get(part, "kind") ?? Reflect.get(part, "media_type");
return Boolean(kind); // mirror the branches promptInputFilePartToFile handles Try / catch
try { files = await Promise.all(message.files.map(promptInputFilePartToFile)); } catch (e) { toast(`Attachment issue: ${e.message}`); return; // keep the draft intact for the user to fix } Prevention
- Validate file parts at attach time (drop/paste), not at send time, so users learn immediately.
- Keep the editor's emitted part kinds and the converter's supported kinds in one shared type.
- Surface which attachment failed rather than only a count.
When it happens
Trigger: message.files contains a file UI part whose format promptInputFilePartToFile does not handle (returns null) — e.g. a part with no underlying blob/URL data, an inline base64 part with a corrupt data URL, or a part kind introduced by a newer editor that this converter predates.
Common situations: Pasting an image whose transfer failed in the browser, a dragged file part constructed by an outdated extension of the prompt editor, or version skew between the chat input component and the converter in hooks.ts.
Related errors
- Thread is not ready for file upload.
- Upload failed
- Failed to update MCP configuration
- Thread history returned an invalid response.
- Failed to load upload limits
AI-assisted analysis of bytedance/deer-flow@1dd6ba1acb (2026-08-14).
Data as JSON: /api/errors/3fe4b6f3f3e35738.
Report an issue: GitHub.