Common publishing errors explained

Top 10 publishing errors with cause + fix. Pre-flight via /campaign-drafts/:id/preflight catches most before publish.

Written By Salvatore Sinigaglia

Last updated About 2 hours ago

Top 10 publishing errors with cause + fix. Pre-flight via /campaign-drafts/:id/preflight catches most before publish.

Common publishing errors explained

Wevion validates campaigns via apps/backend/src/services/campaign-validation.service.ts (verified). Errors surface as ValidationIssue objects with code, fieldPath, message, optional metaErrorCode, and severity. Pre-flight (POST /api/v1/campaign-drafts/:id/preflight) catches most issues before publish. Field-level validation (POST /:id/validate-field) on blur catches earlier.

Who is this for

Mediabuyers hitting validation errors in Express, Pro, or Bulk Launch. Anyone wondering "what does INVALID_AGE_RANGE actually mean".

ValidationIssue structure

Verified apps/backend/src/types/campaigns/validation.types.ts:

interface ValidationIssue {  code: string             // e.g. "INVALID_AGE_RANGE"  fieldPath: string        // e.g. "adSets[0].targeting.ageMin"  message: string          // human-friendly description  metaErrorCode?: number   // Meta API error code if from Meta side  severity: 'error' | 'warning' | 'info'}

Errors block publish; warnings allow but flag concerns; info is informational.

Most common errors

All codes below are verified against campaign-validation.service.ts.

1. INVALID_AGE_RANGE

fieldPath: adSets[N].targeting.ageMin or ageMax

Cause: age range out of acceptable bounds β€” typically ageMin < 13 (Meta minimum) OR ageMax > 65 (Meta upper bound, unless 65+).

Fix: set age range 13-65 (or 13-65+) per Meta minimum age policy. Some categories require 18+ (CREDIT/EMPLOYMENT/HOUSING β€” see cc-120).

2. PIXEL_REQUIRED_FOR_CONVERSION

fieldPath: ads[N].conversionPixelId

Cause: campaign objective is conversion-based (Sales / Leads) but no pixel selected.

Fix: pick a pixel from the dropdown OR set up new pixel in Meta Events Manager. See meta-105 pixels and CAPI.

Note: Wevion's pre-flight does not have an audience-size validation code β€” there is no AUDIENCE_TOO_NARROW. A too-small audience shows up as low estimated reach / slow delivery on the ad platform, not as a Wevion error.

3. DSA_FIELDS_REQUIRED_FOR_EU

fieldPath: campaign.dsaBeneficiary / campaign.dsaPayor

Cause: targeting includes an EU country but the DSA beneficiary/payor fields are empty.

Fix: enter the legal entity benefiting from and paying for the ad (your company's legal name, or the client's for an agency). See cc-120 EU compliance.

4. BUDGET_TOO_LOW

fieldPath: campaign.dailyBudget or adSets[N].dailyBudget

Cause: budget below platform's minimum:

  • Meta: ~$1/day daily (currency-converted)
  • Google: ~$1/day
  • TikTok: ~$5/day for some objectives
  • Snapchat: ~$5/day

Fix: increase the daily budget above the platform minimum.

5. INVALID_CTA_FOR_OBJECTIVE

fieldPath: ads[N].cta

Cause: CTA doesn't match objective (e.g. SHOP_NOW with Awareness objective).

Fix: pick CTA aligned with objective. For Sales/Leads: SHOP_NOW, SIGN_UP, BOOK_NOW. For Awareness/Traffic: LEARN_MORE, WATCH_MORE. See cc-115 ad copy.

6. Creative spec errors (INVALID_IMAGE_DIMENSIONS, IMAGE_FILE_SIZE_EXCEEDED, VIDEO_FILE_SIZE_EXCEEDED, INVALID_VIDEO_DURATION, MEDIA_REQUIRED / CREATIVE_REQUIRED)

fieldPath: ads[N].creative

Cause: creative doesn't meet platform's spec (wrong dimensions, file too large, unsupported duration) or is missing entirely.

Fix:

  • For dimensions: re-crop or re-upload native ratio (1:1, 9:16, 16:9 per placement)
  • For file size: compress or split
  • For format/duration: use supported formats and durations
  • See cc-113 images, cc-114 videos

7. URL_REQUIRED

fieldPath: ads[N].destinationUrl

Cause: campaign objective requires a destination (Traffic / Sales / Leads / App) but the URL field is empty.

Fix: enter a valid HTTPS URL. URL must:

  • Be reachable (no 404)
  • Have HTTPS (HTTP rejected by most platforms)
  • Match your domain (if domain verification required by Meta for iOS 14.5+ β€” see meta-105)

(A malformed URL surfaces as INVALID_URL_FORMAT.)

8. SPECIAL_AD_CATEGORY_RESTRICTIONS

fieldPath: campaign.specialAdCategory or adSets[N].targeting

Cause: a special ad category is set (CREDIT/EMPLOYMENT/HOUSING/SOCIAL_ISSUES) but targeting includes restricted dimensions (narrow age, ZIP for housing, certain interests).

Fix: remove the restricted targeting:

  • For HOUSING: no ZIP code targeting allowed
  • For all special categories: full age range 18-65+, gender = All
  • For SOCIAL_ISSUES_ELECTIONS_OR_POLITICS: complete authorized advertiser verification with Meta first

See cc-120 EU compliance + special categories.

Other common errors

CodeCauseFix
AD_PAGE_REQUIREDMeta campaign needs a Page selected for the ad sourcePick a Page from the dropdown (see meta-104)
INVALID_BID_STRATEGYBid strategy incompatible with the objective/optimization goalPick a compatible bid strategy (see cc-107 budget CBO vs ABO)
INVALID_OPTIMIZATION_GOAL / OPTIMIZATION_GOAL_REQUIREDOptimization goal missing or not valid for the objectivePick a valid optimization goal (cc-106)
BILLING_EVENT_REQUIRED / INVALID_BILLING_EVENTBilling event missing or incompatiblePick a valid billing event
ADSET_BUDGET_REQUIRED / BUDGET_REQUIRED_FOR_CBO / ADSET_BUDGET_DISALLOWED_FOR_CBOBudget missing where required, or set at the wrong level for CBO/ABOSet the budget at the correct level (campaign for CBO, ad set for ABO)
FLEXIBLE_MEDIA_COUNT / CAROUSEL_CARD_COUNTMedia asset count out of the allowed range (Flexible = 2-10 assets)Add/remove assets to fit the range
INVALID_URL_FORMATURL has formatting issuesVerify HTTPS + valid format; no extra spaces/quotes
LIFETIME_BUDGET_REQUIRES_END_TIMEA lifetime-budget setup is missing its end timeProvide an end time
START_TIME_IN_PAST / END_TIME_BEFORE_START_TIMESchedule times are invalidFix the start/end times
NO_VALID_TOKEN / AD_ACCOUNT_NOT_ACTIVEThe connected token is invalid or the ad account isn't activeReconnect the platform / activate the ad account
PREFLIGHT_ERRORGeneric pre-flight failure (may carry metaErrorCode)Read the message; look up any Meta error code in Meta's Marketing API docs

How validation runs

Field-level (real-time)

POST /api/v1/campaign-drafts/:id/validate-field triggers on blur of each field. Inline error shown immediately. Surfaces issues like INVALID_AGE_RANGE, BUDGET_TOO_LOW as you type.

Pre-flight (before publish)

POST /api/v1/campaign-drafts/:id/preflight runs comprehensive validation. Returns ValidationResult:

{  errors: ValidationIssue[],    // block publish  warnings: ValidationIssue[],  // allow with confirm  info: ValidationIssue[],      // informational  valid: boolean                // overall pass/fail}

If errors > 0: publish blocked. Modal shows full list with fix suggestions.

Dry-run (simulate without publishing)

POST /api/v1/campaign-drafts/:id/dry-run simulates publish via launch provider's dry_run mode. Returns what would happen without actually creating campaigns. Useful for last-mile verification.

Bulk Launch validation

Per-row + cross-row validation:

  • Per row: same rules as single campaign
  • Cross-row: duplicate campaign names within an account, conflicting bid amounts on the same account

Failed rows surface in red on the grid; click row for full error detail. Fix individual rows + retry just those.

Validation severity

SeverityBehavior
errorPublish blocked; must fix before continuing
warningPublish allowed; modal asks for explicit confirmation
infoJust FYI; no action required

Don't ignore warnings β€” they often catch suboptimal setups (creative spec might cut off, primary text nearing its limit, etc.).

What you'll see

In Express creative step:

  • Red field highlight + tooltip on error
  • Pre-flight summary at top of review step

In Pro mode:

  • Validation badge per node (campaign/adset/ad) in structure tree
  • Inline per-field errors
  • Top-bar "N errors, M warnings" summary

In Bulk Launch grid:

  • Per-cell red border on errors
  • Per-row red badge with error count
  • Bottom-bar "X rows, Y errors, Z warnings"

Best practices

Read the message, not just the code

Error message has the specific fix suggestion. Codes are just for tracking.

Use pre-flight before every publish

Even if no field-level errors during editing: run preflight. Catches cross-field issues.

For Bulk Launch: validate before publishing all

Toolbar "Validate all" runs full preflight on every row. Fix failures before clicking Publish all.

Build templates with known-good config

Campaign templates saved from successfully-published campaigns avoid the most-common errors automatically.

FAQ

How does Wevion catch publishing errors before I launch?

Wevion runs pre-flight validation via POST /api/v1/campaign-drafts/:id/preflight, which catches most issues before publish. Field-level validation via validate-field triggers on blur to surface problems even earlier as you type. Errors block publish, warnings allow publishing with confirmation, and info-severity issues are just FYI.

What does the PIXEL_REQUIRED_FOR_CONVERSION error mean?

PIXEL_REQUIRED_FOR_CONVERSION means your campaign objective is conversion-based (Sales or Leads) but no pixel is selected. Its fieldPath points to ads[N].conversionPixelId. Fix it by picking a pixel from the dropdown, or set up a new pixel in Meta Events Manager, then re-run pre-flight to confirm the error clears.

Does Wevion block a campaign for a too-narrow audience?

No. Wevion's pre-flight has no audience-size validation code β€” there is no AUDIENCE_TOO_NARROW. A too-small audience shows up as low estimated reach and slow delivery on the ad platform, not as a Wevion error. Broaden it by adding countries, expanding the age range, removing interest layers, or using a lookalike instead of a narrow custom audience.

What's the difference between an error and a warning?

Errors block publish and must be fixed before continuing. Warnings allow publishing but the modal asks for explicit confirmation, since they often flag suboptimal setups like an audience that is narrow but not blocked. Info-severity issues are just FYI and need no action. Don't ignore warnings β€” they catch things you'd otherwise miss.

Can I simulate a publish without creating real campaigns?

Yes. Wevion offers a dry-run via POST /api/v1/campaign-drafts/:id/dry-run, which simulates publish through the launch provider's dry_run mode and returns what would happen without actually creating campaigns. It's useful for last-mile verification before a real launch.