moeru-ai/airi · error · Error

ComfyUI upload failed: ${error}

Error message

ComfyUI upload failed: ${error}

What it means

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.

Source

Thrown at apps/stage-tamagotchi/src/main/services/airi/widgets/providers/comfyui.ts:366

    const buffer = Buffer.from(base64, 'base64')

    // 2. Prepare multipart form data
    const formData = new FormData()
    const fileName = `vhack_${Date.now()}.png`

    // Electron/Node 18+ fetch handles Blobs in FormData
    const blob = new Blob([buffer], { type: 'image/png' })
    formData.append('image', blob, fileName)
    formData.append('overwrite', 'true')

    const response = await this.fetchWithTimeout(`${this.serverUrl}/upload/image`, {
      method: 'POST',
      body: formData,
    }, 60000) // 1 minute timeout for uploads

    if (!response.ok) {
      const error = await response.text()
      throw new Error(`ComfyUI upload failed: ${error}`)
    }

    const data = await response.json()
    return data.name // Returns the filename in ComfyUI's input folder
  }

  private replacePlaceholders(obj: any, replacements: Record<string, string>): any {
    if (typeof obj === 'string') {
      let result = obj
      for (const [placeholder, value] of Object.entries(replacements)) {
        result = result.replace(new RegExp(placeholder.replace(/[.*+?^${}()|[\]\\/]/g, '\\$&'), 'g'), value)
      }
      return result
    }

    if (Array.isArray(obj))
      return obj.map(item => this.replacePlaceholders(item, replacements))

View on GitHub (pinned to 27111382b4)

Solutions

  1. Read the captured response body text in the error to see ComfyUI's rejection reason.
  2. Free disk space on the ComfyUI host's input folder.
  3. Raise any reverse-proxy body-size limit (e.g. client_max_body_size) above the image size.
  4. Confirm the ComfyUI version exposes /upload/image and accepts the 'image' + 'overwrite' form fields.
Defensive patterns

Strategy: try-catch

Validate before calling

// Pre-flight: confirm ComfyUI accepts uploads and host has space
async function canUpload(serverUrl: string): Promise<boolean> {
  try {
    const r = await fetch(`${serverUrl}/system_stats`, { signal: AbortSignal.timeout(5000) })
    return r.ok
  } catch {
    return false
  }
}

Try / catch

try {
  return await provider.uploadImage(buffer)
} catch (e) {
  if (/upload failed/.test(errorMessageFrom(e) ?? '')) {
    // surface the captured body; common: disk full or body-size limit
    throw e
  }
  throw e
}

Prevention

When it happens

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

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

Related errors


AI-assisted analysis of moeru-ai/airi@27111382b4 (2026-08-12). Data as JSON: /api/errors/cff7f5ab7c795151. Report an issue: GitHub.