gitroomhq/postiz-app · error · BadBody

Could not determine the media size for upload

Error message

Could not determine the media size for upload

What it means

SkoolProvider.uploadMediaToSkool does a HEAD request to the media URL to determine size/type before uploading; if the HEAD response is not ok or lacks content-length it throws this BadBody. Marked as a permanent condition so Temporal does not retry uselessly.

Source

Thrown at libraries/nestjs-libraries/src/integrations/social/skool.provider.ts:226

    for (const item of media) {
      // Size and type come from a HEAD request; the PUT below streams the
      // bytes so the file is never buffered in memory.
      const headResponse = await fetch(item.path, {
        method: 'HEAD',
        // identity encoding so content-length matches the bytes the GET streams
        headers: { 'accept-encoding': 'identity' },
        // @ts-ignore - undici-only option; blocks SSRF to internal IPs
        dispatcher: getSsrfSafeDispatcher(),
      });
      const contentType =
        headResponse.headers.get('content-type') || 'application/octet-stream';
      const contentLength = Number(
        headResponse.headers.get('content-length') || 0
      );
      if (!headResponse.ok || !contentLength) {
        // A permanent condition - fail fast instead of letting Temporal retry
        throw new BadBody(
          this.identifier,
          '{}',
          '{}',
          'Could not determine the media size for upload'
        );
      }
      const fileName = item.path.split('/').pop() || 'file';

      const createFileResponse = await (
        await this.fetch('https://api2.skool.com/files', {
          method: 'POST',
          headers: {
            'Content-Type': 'application/json',
            Cookie: `auth_token=${cookies.auth_token}; client_id=${cookies.client_id}`,
          },
          body: JSON.stringify({
            file_name: fileName,
            content_type: contentType,

View on GitHub (pinned to 0f1647f749)

Solutions

  1. curl -I the media URL from the server and confirm 200 + content-length
  2. Fix storage/public-URL configuration (BACKEND_URL, signed URL TTL)
  3. Re-add the media file and retry the post
  4. If the CDN omits content-length, serve media from a source that includes it
Defensive patterns

Strategy: validation

Validate before calling

const head = await fetch(url, { method: 'HEAD' });
if (!head.ok || !Number(head.headers.get('content-length'))) {
  throw new Error('Media URL lacks size info; fix storage first');
}

Prevention

When it happens

Trigger: HEAD media.url returns non-200 or a missing/zero content-length header — storage signed URL expired, file deleted, or server not returning content-length (chunked).

Common situations: Expired S3/cloud URLs, deleted media library entries, misconfigured BACKEND_URL/storage, or a CDN stripping content-length from HEAD responses.

Related errors


AI-assisted analysis of gitroomhq/postiz-app@0f1647f749 (2026-08-27). Data as JSON: /api/errors/533d9eba7ae47edd. Report an issue: GitHub.