{"record":{"id":"4f1a888a74868b89","repo":"gitroomhq/postiz-app","slug":"validation-name-your-post-should-have-at-least","errorCode":null,"errorMessage":"${validation.name}: Your post should have at least one character or one image.","messagePattern":"(.+?): Your post should have at least one character or one image\\.","errorType":"validation","errorClass":"BadRequestException","httpStatus":400,"severity":"error","filePath":"libraries/nestjs-libraries/src/database/prisma/posts/posts.service.ts","lineNumber":1053,"sourceCode":"      return {\n        id: p.id,\n        content: p.content,\n        delay: p.delay || 0,\n        image,\n      };\n    });\n\n    // Same server-side validation as the dashboard / public create route.\n    const [validation] = await this.validatePosts(orgId, [\n      {\n        integration: { id: integration.id },\n        settings: mergedSettings,\n        value: value.map((p) => ({ content: p.content, image: p.image })),\n      },\n    ]);\n\n    if (validation.emptyContent) {\n      throw new BadRequestException(\n        `${validation.name}: Your post should have at least one character or one image.`\n      );\n    }\n\n    if (root.state !== 'DRAFT') {\n      if (!validation.valid) {\n        throw new BadRequestException(\n          `${validation.name}: ${\n            validation.settingsError || 'Please fix your settings'\n          }`\n        );\n      }\n\n      if (validation.errors !== true) {\n        throw new BadRequestException(\n          `${validation.name}: ${validation.errors}`\n        );\n      }","sourceCodeStart":1035,"sourceCodeEnd":1071,"githubUrl":"https://github.com/gitroomhq/postiz-app/blob/0f1647f7491a217d43eb5ae7a480484bdf0aff3e/libraries/nestjs-libraries/src/database/prisma/posts/posts.service.ts#L1035-L1071","documentation":"Per-provider validation (Zod schemas in libs/.../validation) checks that each post variant has content or media. emptyContent=true means the target channel received a post with no text and no image, which the provider rejects.","triggerScenarios":"Creating/updating a post where a per-channel variant has empty content and an empty/undefined image array (e.g. clearing the text box for one channel while drafting).","commonSituations":"Multi-channel composer with an emptied per-channel override; image upload failing silently leaving posts with neither text nor media; API payloads with content: '' and image: [].","solutions":["Add at least one character of content or attach an image to every channel variant","Remove the empty per-channel variant from the posts array instead of submitting it blank","Check that image URLs survived upload; re-upload if the media failed","Validate client-side per provider: content.trim() || image.length"],"exampleFix":"// before\n{ integration: { id }, content: '', image: [] }\n// after\n{ integration: { id }, content: 'Check this out!', image: [] }\n// or\n{ integration: { id }, content: '', image: [uploadedImageUrl] }","handlingStrategy":"validation","validationCode":"const hasContent = body.posts.every((p) => (p.content ?? '').trim().length > 0 || (p.image ?? []).length > 0);\nif (hasContent) await createPost(orgId, body);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Require text or media per channel variant in the composer","Confirm image uploads succeeded before submit","Strip fully-empty variants from the payload"],"tags":["posts","validation","content","provider","composer"],"backgroundTag":"schema-validation-failed","analyzedSha":"0f1647f7491a217d43eb5ae7a480484bdf0aff3e","analyzedAt":"2026-08-27T12:09:55.020Z","schemaVersion":2},"datasetVersion":"2026-08-27T13:17:12.746Z"}