gitroomhq/postiz-app · error · BadBody

handleError.value

Error message

handleError.value

What it means

In checkPostStatus, when X is asked about a pending tweet, a bad-body type error from handleErrors causes rethrowing the provider error with handleError.value as the user-facing message. It reflects X's own API error body for the status/create call.

Source

Thrown at libraries/nestjs-libraries/src/integrations/social/x.provider.ts:863

      let processing:
        | { state: string; check_after_secs?: number; error?: { message?: string } }
        | undefined;
      try {
        processing = await this.mediaProcessingStatus(client, mediaId);
      } catch (err: any) {
        // twitter-api-v2 throws ApiResponseError, which never passes through
        // this.fetch/handleErrors: classify it here so revoked tokens and
        // suspended accounts fail properly instead of burning the whole check
        // budget as "transient".
        const body = JSON.stringify(err?.data || {});
        const handleError = this.handleErrors(body);

        if (err?.code === 401 || handleError?.type === 'refresh-token') {
          throw new RefreshToken(this.identifier, body, Buffer.from('{}'));
        }

        if (handleError?.type === 'bad-body') {
          throw new BadBody(
            this.identifier,
            body,
            Buffer.from('{}'),
            handleError.value
          );
        }

        // Transient status-check error: the media may finish transcoding just
        // fine, keep polling - if X stays broken the workflow exhausts its
        // checks and warns the user properly.
        return { status: 'pending', pendingData };
      }

      if (processing?.state === 'failed') {
        throw new BadBody(
          this.identifier,
          JSON.stringify(processing),
          Buffer.from('{}'),

View on GitHub (pinned to 0f1647f749)

Solutions

  1. Read handleError.value / the raw body attached to the BadBody — it is X's actual error message
  2. Address the specific X error (e.g. duplicate status text, rate limit) and retry
  3. If it is a refresh-token type error instead, the provider throws RefreshToken and the channel needs reconnecting
  4. Retry after limits reset if the message indicates rate limiting
Defensive patterns

Strategy: try-catch

Type guard

const isBadBodyError = (e: unknown): e is BadBody => e instanceof BadBody;

Try / catch

catch (e) { if (e instanceof BadBody && e.identifier === 'x') { const msg = e.message; /* surface X's message; handle duplicate/limit cases specially */ } throw e; }

Prevention

When it happens

Trigger: The status-check request to X returns an error body that handleErrors classifies as 'bad-body' (non-auth error such as invalid request, duplicate content, over limit), so the original error is re-raised as BadBody with X's message.

Common situations: Posting duplicate content X rejects; exceeding rate/token limits mid-post; malformed status parameters for the pending post.

Related errors


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