yikart/AiToEarn · error · InstagramPlatformException

15070

15070

Error message

{{platform}} platform API request failed

What it means

InstagramService's axios interceptor converts every failed Graph API request into an InstagramPlatformException with ResponseCode.ChannelPlatformApiFailed (15070). Network-level Axios failures (no response) and non-2xx responses from graph.facebook.com (or the configured graphApiBaseUrl) are both wrapped, with the Instagram error body parsed for platform code/message. The exception records endpoint, method, HTTP status, category, retryability, and the raw platform payload.

Source

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

import { InstagramConfig } from './instagram.config'
import { InstagramPlatformException } from './instagram.exception'
import { InstagramOAuthGrantType } from './instagram.interface'
import { InstagramMediaContainerStatusResponseSchema, InstagramMediaType } from './instagram.schema'

@Injectable()
export class InstagramService {
  private readonly http: AxiosInstance

  constructor(private readonly cfg: InstagramConfig) {
    this.http = this.createHttpClient()
  }

  private createHttpClient(): AxiosInstance {
    const http = axios.create()
    http.interceptors.response.use(
      response => response,
      (error: AxiosError<InstagramErrorBody>) => {
        throw InstagramPlatformException.fromAxiosError(error)
      },
    )
    return http
  }

  private get graphApiBaseUrl(): string {
    return `https://graph.instagram.com/${this.cfg.graphApiVersion}`
  }

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

View on GitHub (pinned to d3aa8bea5b)

Solutions

  1. Inspect the thrown InstagramPlatformException's cause (platformCode, platformMessage, httpStatus) to get Meta's specific error subcode and message.
  2. If httpStatus is 401/190 (invalid token), re-authenticate the channel or refresh the long-lived token before retrying.
  3. If the error indicates missing permission (code 200/102), re-run OAuth with instagram_basic, instagram_content_publish, pages_show_list scopes and re-link the account.
  4. If retryable (429/5xx/network), back off and retry; Meta rate limits require waiting per X-Business-Use-Case-Usage headers.
  5. Confirm the target account is an Instagram Business/Creator account linked to a Facebook Page, and that the configured Graph API version is still supported.

Example fix

// before: expired token causes 190 error wrapped as 15070
const res = await this.http.get(`${this.graphApiBaseUrl}/${igUserId}?fields=followers_count`, { params: { access_token: token } })

// after: detect token failure and refresh
try {
  const res = await this.http.get(`${this.graphApiBaseUrl}/${igUserId}`, { params: { fields: 'followers_count', access_token: token } })
} catch (e) {
  if (e instanceof InstagramPlatformException && e.cause?.platformCode === 190) {
    token = await this.refreshLongLivedToken(channel)
    // retry request with new token
  } else throw e
}
Defensive patterns

Strategy: try-catch

Validate before calling

// pre-flight: token present, not expired, and account is a linked IG business account
if (!accessToken || tokenExpiresAt <= new Date()) await refreshLongLivedToken(channel)
if (!igUserId) throw new Error('Channel has no linked instagram_business_account; re-link via OAuth')

Type guard

function isInstagramPlatformException(e: unknown): e is InstagramPlatformException {
  return e instanceof InstagramPlatformException
}

Try / catch

try {
  const result = await instagramService.publish(accessToken, igUserId, payload)
} catch (e) {
  if (e instanceof InstagramPlatformException) {
    if (e.cause?.platformCode === 190 || e.cause?.httpStatus === 401) {
      // refresh token and retry once
    } else if (e.retryable) {
      // backoff retry (429 / 5xx / network)
    } else {
      // surface cause.platformMessage to the channel owner
    }
  } else throw e
}

Prevention

When it happens

Trigger: Any request through this.http — publishing media, fetching Instagram business account info, querying insights, exchanging tokens — that returns a non-2xx Graph API response (invalid OAuth token, missing instagram_business_account, permission denied, rate limit, invalid media params) or fails at the network level (timeout, DNS, connection refused).

Common situations: Facebook/Instagram access token expired or app-scoped token lacking instagram_basic/instagram_content_publish permissions; account not converted to an Instagram Business/Creator account and not linked to a Facebook Page; Graph API version deprecation after version changes; Meta rate limiting (code 4, 613) during bulk posting; egress blocked to graph.facebook.com.

Related errors


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