hcengineering/platform · error · Error

Failed to upload attachment file: ${file.name}

Error message

Failed to upload attachment file: ${file.name}

What it means

uploadAttachment delegates the actual file transfer to this.fileUploader.uploadFile(id, file). When the uploader reports success === false, the importer throws this error naming the file, since the attachment blob is required before an Attachment doc can be added via client.addCollection.

Source

Thrown at packages/importer/src/importer/importer.ts:955

          await this.createDrawing(blobId, drawing, spaceId)
        }
      }
    } catch {
      this.logger.error('Failed to upload attachment file: ', attachment.title)
    }
  }

  private async createAttachment (
    id: Ref<Attachment>,
    spaceId: Ref<Space>,
    parentId: Ref<Doc>,
    parentClass: Ref<Class<Doc<Space>>>,
    file: File,
    metadata?: ImportImageMetadata
  ): Promise<Ref<PlatformBlob>> {
    const uploadResult = await this.fileUploader.uploadFile(id, file)
    if (!uploadResult.success) {
      throw new Error('Failed to upload attachment file: ' + file.name)
    }
    await this.client.addCollection(
      attachment.class.Attachment,
      spaceId,
      parentId,
      parentClass,
      'attachments',
      {
        file: uploadResult.id,
        lastModified: Date.now(),
        name: file.name,
        size: file.size,
        type: file.type,
        metadata
      },
      id
    )
    return uploadResult.id

View on GitHub (pinned to 63e28dc964)

Solutions

  1. Check the fileUploader configuration (service URL, credentials, bucket) and server logs for the underlying upload failure cause
  2. Verify connectivity to the file storage service from the importer environment
  3. Confirm the file size is within the server's upload limits; compress or skip oversized files
  4. Inspect/retry the upload — add retry logic around importAttachment or re-run the import; failed uploads are not retried automatically

Example fix

// before
await importer.uploadAttachment(spaceId, parentId, parentClass, largeFile) // > server limit
// after
if (largeFile.size <= MAX_UPLOAD_SIZE) {
  await importer.uploadAttachment(spaceId, parentId, parentClass, largeFile)
} else {
  console.warn('Skipping oversized attachment:', largeFile.name)
}
Defensive patterns

Strategy: try-catch

Validate before calling

const probe = await client.findAll(attachment.class.Attachment, { limit: 1 }) // verifies storage reachability indirectly
if (file.size > MAX_UPLOAD_SIZE) throw new Error(`File too large: ${file.name}`)

Type guard

function isUploadOk(r: { success: boolean }): r is { success: true } {
  return r.success === true
}

Try / catch

try {
  await importAttachmentsWithRetry(attachments)
} catch (err) {
  if (err.message.startsWith('Failed to upload attachment file:')) {
    console.error('Storage/upload failure for:', err.message, '- check file service config and connectivity')
  } else throw err
}

async function importAttachmentsWithRetry(attachments) {
  for (const a of attachments) {
    for (let i = 0; i < 3; i++) {
      try { await doImportAttachment(a); break } catch (e) { if (i === 2) throw e }
    }
  }
}

Prevention

When it happens

Trigger: uploadFile fails — network/auth failure to the storage/Files service, file exceeding size limits, storage bucket misconfiguration, or the target doc id/space being rejected by the upload endpoint.

Common situations: Uploader endpoint unreachable (firewall, wrong service URL/env var); expired or missing upload credentials/token; file larger than the configured max upload size; storage backend (e.g. S3/MinIO) down or misconfigured during migration.

Related errors


AI-assisted analysis of hcengineering/platform@63e28dc964 (2026-08-29). Data as JSON: /api/errors/c0ef1cb37b2209be. Report an issue: GitHub.