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
- Inspect exception.cause (platformCode, httpStatus, platformMessage, raw) to identify the underlying Meta Graph error
- If category is Auth (code 190/expired token), refresh the access token and reconnect the channel
- If retryable=true (network or 5xx), retry the request with backoff
- For rate-limit errors, slow down publishing and honor retry-after
- 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
- Refresh Threads long-lived tokens before the 60-day expiry
- Check exception.retryable and category before deciding to retry
- Log exception.cause.raw to capture the exact Meta Graph error code
- Monitor rate limits and throttle bulk publishing
- Validate token and channel connection state before issuing API calls
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
- 15070
- 15070
- Failed to fetch image: ${response.status} ${response.statusT
- Relay uploadSign returned no uploadUrl: ${JSON.stringify(sig
- S3DownloadFileFailed
AI-assisted analysis of yikart/AiToEarn@d3aa8bea5b (2026-08-31).
Data as JSON: /api/errors/f87f91336d8e406a.
Report an issue: GitHub.