gitroomhq/postiz-app · error · PostValidationException

Post validation failed

Error message

Post validation failed

What it means

createPost runs posts through _postsService.validatePosts; the local fail() helper throws PostValidationException with 'Post validation failed' carrying per-post details (provider identifier, name, and the specific error). This is the generic envelope for any rule the post violates — the actionable detail is in the exception payload, not the message.

Source

Thrown at apps/backend/src/public-api/routes/v1/public.integrations.controller.ts:231

      )
    ) {
      throw new HttpException(
        {
          msg: `All media must be uploaded through our upload API route and contain the domain: ${process.env.RESTRICT_UPLOAD_DOMAINS}`,
        },
        400
      );
    }

    // Server-side validation — same rules as the dashboard, surfaced as a
    // readable 400 (see PostValidationExceptionFilter).
    const validation = await this._postsService.validatePosts(
      org.id,
      body.posts
    );

    const fail = (item: (typeof validation)[number], error: string) => {
      throw new PostValidationException({
        provider: item.identifier,
        name: item.name,
        error,
      });
    };

    for (const item of validation) {
      if (item.emptyContent) {
        fail(
          item,
          'Your post should have at least one character or one image.'
        );
      }
    }

    if (body.type !== 'draft') {
      for (const item of validation) {
        if (!item.valid) {

View on GitHub (pinned to 0f1647f749)

Solutions

  1. Inspect the exception response body — provider/name/error fields identify exactly which post and which rule failed
  2. Verify each post's identifier matches a currently connected integration for the organization
  3. Ensure content/media satisfy the target provider's requirements (text length, media count/type)
  4. Correct date formats and retry, fixing posts one at a time if the payload is large

Example fix

// before
{ "posts": [{ "integration": { "id": "disconnected-channel" }, "value": [] }] }

// after
{ "posts": [{ "integration": { "id": "connected-channel" }, "value": [{ "content": "Hello!" }] }] }
Defensive patterns

Strategy: try-catch

Validate before calling

// Pre-validate your payload shape before sending
for (const post of posts) {
  if (!post.integration?.id) throw new Error('Missing integration id');
  if (!post.value?.length) throw new Error('Post has no content entries');
  for (const v of post.value) {
    if (!v.content?.trim() && !(v.image?.length || v.video?.length)) {
      throw new Error('Entry needs text or media');
    }
  }
}

Type guard

null

Try / catch

try {
  await api.createPost({ posts });
} catch (e) {
  if (e instanceof PostValidationException || e?.response?.data?.msg === 'Post validation failed') {
    const { provider, name, error } = e.response.data; // per-post detail drives the fix
    console.error(`Post for ${provider}/${name} failed: ${error}`);
  }
}

Prevention

When it happens

Trigger: POST /public/v1/posts where one of the posts fails service-level validation: missing/invalid integration reference, empty content for a provider requiring text, invalid scheduling, unsupported media for the target provider, deleted/disconnected channel, etc. Any per-post rule inside validatePosts trips it.

Common situations: Referencing an integration that was disconnected; sending image-only posts to a text-only provider; malformed date/ISO strings; posts whose media list doesn't satisfy the provider's requirements.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


AI-assisted analysis of gitroomhq/postiz-app@0f1647f749 (2026-08-27). Data as JSON: /api/errors/39bcb42406f8a160. Report an issue: GitHub.