yikart/AiToEarn · error · ThreadsPlatformException

15070

15070

Error message

{{platform}} platform API request failed

What it means

ThreadsService.request() wraps every raw call to https://graph.threads.net (data, listWorks, createContainer, publishContainer, getContainerStatus, getPublishedPost). Any AxiosError is converted via ThreadsPlatformException.fromAxiosError into a ChannelPlatformException with ResponseCode.ChannelPlatformApiFailed (15070). No Axios response means category Network and retryable=true; a Graph error body is classified by status/Meta error code (auth, rate-limit, media, etc.).

Source

Thrown at project/aitoearn-backend/apps/aitoearn-server/src/core/channels/platforms/threads/threads.service.ts:43

import { ThreadsPlatformException } from './threads.exception'
import { ThreadsOAuthGrantType } from './threads.interface'

@Injectable()
export class ThreadsService {
  private readonly logger = new Logger(ThreadsService.name)
  private readonly apiBaseUrl = 'https://graph.threads.net'

  constructor(private readonly cfg: ThreadsConfig) {}

  private async request<T>(url: string, config: AxiosRequestConfig = {}): Promise<T> {
    this.logger.debug(`[Threads] ${config.method ?? 'GET'} ${url}`)
    try {
      const response: AxiosResponse<T> = await axios(url, config)
      return response.data
    }
    catch (error) {
      if (axios.isAxiosError<ThreadsErrorBody>(error)) {
        throw ThreadsPlatformException.fromAxiosError(error)
      }
      throw error
    }
  }

  generateAuthUrl(scopes: string[], state: string): string {
    const params = new URLSearchParams({
      client_id: this.cfg.clientId,
      redirect_uri: this.cfg.redirectUri,
      scope: scopes.join(','),
      response_type: 'code',
      state,
    })

    return `https://threads.net/oauth/authorize?${params.toString()}`
  }

  async exchangeCode(code: string): Promise<{

View on GitHub (pinned to d3aa8bea5b)

Solutions

  1. Inspect exception.cause (platformCode, httpStatus, platformMessage, raw) to identify the underlying Meta Graph error
  2. If category is Auth (code 190/expired token), refresh the access token and reconnect the channel
  3. If retryable=true (network or 5xx), retry the request with backoff
  4. For rate-limit errors, slow down publishing and honor retry-after
  5. Verify Threads app config: client id/secret, redirect URI, and requested scopes

Example fix

// before
const data = await threadsService.request(url, config) // throws 15070
// after
try {
  const data = await threadsService.request(url, config)
} catch (e) {
  if (e instanceof ChannelPlatformException && e.cause?.type === PlatformErrorCauseType.Network && e.retryable) {
    await sleep(backoff); return retry()
  }
  throw e
}
Defensive patterns

Strategy: try-catch

Validate before calling

if (!accessToken) throw new Error('Threads channel is not connected; re-authorize before calling the API')

Type guard

function isChannelPlatformException(e: unknown): e is ChannelPlatformException {
  return e instanceof ChannelPlatformException
}

Try / catch

try {
  const data = await threadsService.request(url, config)
} catch (e) {
  if (e instanceof ChannelPlatformException) {
    if (e.retryable) return retryWithBackoff()
    if (e.category === PlatformErrorCategory.Auth) return markChannelNeedsReauth()
    logger.error({ code: e.code, cause: e.cause }, 'Threads API failed')
  }
  throw e
}

Prevention

When it happens

Trigger: Any Threads Graph API call fails: network/DNS/timeout (error.response undefined), HTTP 4xx/5xx from graph.threads.net, invalid or expired access token, Meta Graph error body (e.g. code 190 invalid token, 4 rate limit, media processing errors), or wrong redirect_uri/client_id during token exchange.

Common situations: Expired Threads long-lived token after 60 days; revoked app permissions; Meta app in development mode; Threads API rate limits on publishing bursts; transient network failures or proxy blocks to graph.threads.net; incorrect THREADS_CLIENT_SECRET/redirect URI config.

Related errors


AI-assisted analysis of yikart/AiToEarn@d3aa8bea5b (2026-08-31). Data as JSON: /api/errors/f87f91336d8e406a. Report an issue: GitHub.