{"record":{"id":"cff7f5ab7c795151","repo":"moeru-ai/airi","slug":"comfyui-upload-failed-error","errorCode":null,"errorMessage":"ComfyUI upload failed: ${error}","messagePattern":"ComfyUI upload failed: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"apps/stage-tamagotchi/src/main/services/airi/widgets/providers/comfyui.ts","lineNumber":366,"sourceCode":"    const buffer = Buffer.from(base64, 'base64')\n\n    // 2. Prepare multipart form data\n    const formData = new FormData()\n    const fileName = `vhack_${Date.now()}.png`\n\n    // Electron/Node 18+ fetch handles Blobs in FormData\n    const blob = new Blob([buffer], { type: 'image/png' })\n    formData.append('image', blob, fileName)\n    formData.append('overwrite', 'true')\n\n    const response = await this.fetchWithTimeout(`${this.serverUrl}/upload/image`, {\n      method: 'POST',\n      body: formData,\n    }, 60000) // 1 minute timeout for uploads\n\n    if (!response.ok) {\n      const error = await response.text()\n      throw new Error(`ComfyUI upload failed: ${error}`)\n    }\n\n    const data = await response.json()\n    return data.name // Returns the filename in ComfyUI's input folder\n  }\n\n  private replacePlaceholders(obj: any, replacements: Record<string, string>): any {\n    if (typeof obj === 'string') {\n      let result = obj\n      for (const [placeholder, value] of Object.entries(replacements)) {\n        result = result.replace(new RegExp(placeholder.replace(/[.*+?^${}()|[\\]\\\\/]/g, '\\\\$&'), 'g'), value)\n      }\n      return result\n    }\n\n    if (Array.isArray(obj))\n      return obj.map(item => this.replacePlaceholders(item, replacements))\n","sourceCodeStart":348,"sourceCodeEnd":384,"githubUrl":"https://github.com/moeru-ai/airi/blob/27111382b4a79a7e983289d6e983a06af185ed0f/apps/stage-tamagotchi/src/main/services/airi/widgets/providers/comfyui.ts#L348-L384","documentation":"Thrown by the ComfyUI provider's uploadImage when the POST to /upload/image returns a non-ok response. The full response text is captured as the error message. This upload (60s timeout) sends a generated/texture image as multipart/form-data so ComfyUI can reference it by filename in a workflow.","triggerScenarios":"The bidirectional flow uploads an image (texture) to ComfyUI's input folder and the server rejects it — disk full on the ComfyUI host, the upload endpoint disabled/renamed, payload too large, a proxy blocking multipart uploads, or a server-side error during file handling.","commonSituations":"ComfyUI host ran out of disk space; reverse proxy limits body size below the image size; ComfyUI version without /upload/image; the overwrite flag or filename is rejected; transient 5xx during heavy load.","solutions":["Read the captured response body text in the error to see ComfyUI's rejection reason.","Free disk space on the ComfyUI host's input folder.","Raise any reverse-proxy body-size limit (e.g. client_max_body_size) above the image size.","Confirm the ComfyUI version exposes /upload/image and accepts the 'image' + 'overwrite' form fields."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// Pre-flight: confirm ComfyUI accepts uploads and host has space\nasync function canUpload(serverUrl: string): Promise<boolean> {\n  try {\n    const r = await fetch(`${serverUrl}/system_stats`, { signal: AbortSignal.timeout(5000) })\n    return r.ok\n  } catch {\n    return false\n  }\n}","typeGuard":null,"tryCatchPattern":"try {\n  return await provider.uploadImage(buffer)\n} catch (e) {\n  if (/upload failed/.test(errorMessageFrom(e) ?? '')) {\n    // surface the captured body; common: disk full or body-size limit\n    throw e\n  }\n  throw e\n}","preventionTips":["Keep free disk space on ComfyUI's input folder.","Set reverse-proxy body-size limits above the largest expected image.","Confirm the ComfyUI version supports /upload/image with the 'image' + 'overwrite' fields."],"tags":["comfyui","upload","network","artistry"],"backgroundTag":null,"analyzedSha":"27111382b4a79a7e983289d6e983a06af185ed0f","analyzedAt":"2026-08-12T18:33:34.132Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}