gitroomhq/postiz-app · error · BadRequestException
All posts must have an integration id
Error message
All posts must have an integration id
What it means
PostsService.mapTypeToPost requires every entry in body.posts to carry an integration.id before it can map a submitted post to persisted posts. The integration id identifies which connected social channel the post targets; without it the post cannot be routed to a provider.
Source
Thrown at libraries/nestjs-libraries/src/database/prisma/posts/posts.service.ts:254
async getStatistics(orgId: string, id: string) {
const getPost = await this.getPostsRecursively(id, true, orgId, true);
const content = getPost.map((p) => p.content);
const shortLinksTracking = await this._shortLinkService.getStatistics(
content
);
return {
clicks: shortLinksTracking,
};
}
async mapTypeToPost(
body: CreatePostDto,
organization: string,
replaceDraft: boolean = false
): Promise<CreatePostDto> {
if (!body?.posts?.every((p) => p?.integration?.id)) {
throw new BadRequestException('All posts must have an integration id');
}
const mappedValues = {
...body,
type: replaceDraft ? 'schedule' : body?.type,
posts: await Promise.all(
body?.posts?.map(async (post) => {
const integration = await this._integrationService.getIntegrationById(
organization,
post.integration.id
);
if (!integration) {
throw new BadRequestException(
`Integration with id ${post.integration.id} not found`
);
}
View on GitHub (pinned to 0f1647f749)
Solutions
- Ensure every item in posts[] includes the id of a connected integration (e.g. posts: [{ integration: { id: '<integrationId>' }, content: '...' }])
- Validate the payload client-side before submitting: posts.every(p => p?.integration?.id)
- If the integration was deleted, re-connect the channel to get a new integration id and resubmit
- Check the CreatePostDto parsing if a custom client strips unknown properties such as integration
Example fix
// before
{ type: 'schedule', posts: [{ content: 'Hello' }] }
// after
{ type: 'schedule', posts: [{ integration: { id: integrationId }, content: 'Hello' }] } Defensive patterns
Strategy: validation
Validate before calling
const ok = body?.posts?.length > 0 && body.posts.every((p) => p?.integration?.id);
if (!ok) throw new Error('Select a channel for every post variant'); Type guard
const hasIntegrationIds = (b: CreatePostDto): boolean => Array.isArray(b?.posts) && b.posts.length > 0 && b.posts.every((p) => !!p?.integration?.id);
Prevention
- Require a channel selection in the composer before enabling save
- Disable the submit button until every variant has an integration
- Log the payload shape when the 400 arrives to spot stripped fields
When it happens
Trigger: POST /organization/:orgId/posts (createPost) or a draft replace where body.posts contains an item with a missing or null integration, or the posts array itself is undefined (every() on undefined short-circuits the guard via optional chaining and fails).
Common situations: Client sends { posts: [{ content: 'hi' }] } without selecting a channel; integration object dropped by a form state bug; API consumers building payloads manually and omitting integration; draft payloads where integration was not persisted.
Understand the failure class
Background: "Missing required field" and "field is required" errors: why libraries reject payloads that omit mandatory fields — this error's family across 20 libraries.
Related errors
- Integration with id ${post.integration.id} not found
- Post validation failed
- Integration with id ${post?.integration?.id} not found
- This post was already published on ${dayjs .utc(post.publi
- This id belongs to a comment, pass the id of the main post
AI-assisted analysis of gitroomhq/postiz-app@0f1647f749 (2026-08-27).
Data as JSON: /api/errors/191ba3fbe402f698.
Report an issue: GitHub.