gitroomhq/postiz-app · error · BadBody
X could not create the article draft
Error message
X could not create the article draft
What it means
When publishing an X (Twitter) article/long-form post, the draft-creation response has no data.id. The provider logs any returned errors and throws BadBody 'X could not create the article draft', meaning the article never entered draft state.
Source
Thrown at libraries/nestjs-libraries/src/integrations/social/x.provider.ts:1115
: {}),
}),
});
const draftJson = (await draftResponse.json()) as {
data?: { id: string };
errors?: any[];
};
// The articles endpoints can return 2xx with an errors array (e.g. a
// rejected cover) - don't swallow it.
if (draftJson?.errors?.length) {
console.log(
'X article draft returned errors:',
JSON.stringify(draftJson.errors)
);
}
if (!draftJson?.data?.id) {
throw new BadBody(
this.identifier,
JSON.stringify(draftJson),
Buffer.from('{}'),
'X could not create the article draft'
);
}
if (settings.article_status !== 'published') {
return {
status: 'completed',
postId: draftJson.data.id,
releaseURL: `https://x.com/i/articles`,
};
}
const publishUrl = `https://api.x.com/2/articles/${draftJson.data.id}/publish`;
const publishResponse = await this.fetch(publishUrl, {
method: 'POST',View on GitHub (pinned to 0f1647f749)
Solutions
- Inspect draftJson (attached to the BadBody) for the errors array details
- Verify the connected X account has Articles access enabled
- Ensure the OAuth app requests the article/long-form write scopes
- Simplify the article payload (plain text first) to isolate validation failures
Defensive patterns
Strategy: validation
Validate before calling
// before publishing, confirm the account can use articles
const me = await client.get('users/me');
if (!(me.data as any)?.is_article_supported) { /* fall back to a regular post */ } Type guard
const hasArticleDraftId = (j: unknown): j is { data: { id: string } } => Boolean((j as any)?.data?.id); Try / catch
catch (e) { if (e instanceof BadBody && e.message.includes('article draft')) { /* inspect errors array, fall back to normal post if unsupported */ } throw e; } Prevention
- Request article write scopes in the OAuth flow
- Validate article title/body length limits before submitting
- Gate the article path on account capability, with a regular-post fallback
When it happens
Trigger: X's article draft endpoint returns errors array (auth scope missing, validation error on the article payload) or an unexpected envelope without data.id.
Common situations: App/user token lacks the article (long-form) scope; article payload (title/body/markdown) fails X's validation; X Articles feature not enabled for the account; X API change to the article endpoint shape.
Related errors
- X created the article draft but could not publish it, check
- Integration not allowed
- File is too large.
- Unsupported file type.
- All media must be uploaded through our upload API route and
AI-assisted analysis of gitroomhq/postiz-app@0f1647f749 (2026-08-27).
Data as JSON: /api/errors/93eab0325844afa7.
Report an issue: GitHub.