{"record":{"id":"19fe3c2928cc4994","repo":"TryGhost/Ghost","slug":"the-newsletter-parameter-doesn-t-match-any-active","errorCode":null,"errorMessage":"The newsletter parameter doesn't match any active newsletter.","messagePattern":"The newsletter parameter doesn't match any active newsletter\\.","errorType":"http","errorClass":"BadRequestError","httpStatus":400,"severity":"error","filePath":"ghost/core/core/server/models/post.js","lineNumber":797,"sourceCode":"                this.set('published_by', String(userId));\n            }\n        } else {\n            // In any other case (except import), `published_by` should not be changed\n            if (this.hasChanged('published_by') && !options.importing) {\n                this.set('published_by', this.previous('published_by') ? String(this.previous('published_by')) : null);\n            }\n        }\n\n        // newsletter_id is read-only and should only be set using the newsletter param when publishing/scheduling\n        if (options.newsletter\n            && !this.get('newsletter_id')\n            && this.hasChanged('status')\n            && (newStatus === 'published' || newStatus === 'scheduled' || newStatus === 'sent')) {\n            // Map the passed slug to the id + validate the passed newsletter\n            ops.push(async () => {\n                const newsletter = await Newsletter.findOne({slug: options.newsletter}, {transacting: options.transacting, filter: 'status:active'});\n                if (!newsletter) {\n                    throw new BadRequestError({\n                        message: messages.invalidNewsletter\n                    });\n                }\n                this.set('newsletter_id', newsletter.id);\n            });\n\n            // If the `email_segment` isn't passed at the same time, reset it to be 100% sure that they can only be used together\n            this.set('email_recipient_filter', 'all');\n\n            // email_segment is read-only and should only be set using a query param when publishing/scheduling\n            // we can't set it if we don't pass newsletter\n            if (options.email_segment) {\n                this.set('email_recipient_filter', options.email_segment);\n            }\n        }\n\n        // ensure draft posts have the email_recipient_filter reset unless an email has already been sent\n        if (newStatus === 'draft' && this.hasChanged('status')) {","sourceCodeStart":779,"sourceCodeEnd":815,"githubUrl":"https://github.com/TryGhost/Ghost/blob/47d8b0e2ad2fd4757d3bc45f46c3ac165ff8a1fe/ghost/core/core/server/models/post.js#L779-L815","documentation":"A BadRequestError thrown when publishing or scheduling a post and the supplied `newsletter` query parameter (a slug) does not resolve to an active newsletter via `Newsletter.findOne({slug}, {filter: 'status:active'})`. The check only runs when the post is transitioning to published/scheduled/sent without an existing `newsletter_id`. The newsletter must be active — archived newsletters are filtered out.","triggerScenarios":"PUT/PATCH a post to `published`/`scheduled` with `?newsletter=foo` where `foo` is a nonexistent slug, a typo, or the slug of an archived/inactive newsletter. Also when the `status:active` filter excludes the only matching newsletter.","commonSituations":"The newsletter was archived between page load and publish; the client sends the newsletter's UUID/name instead of its slug; a typo in the slug; the newsletter feature is disabled and no active newsletters exist; the slug's case differs from the stored value.","solutions":["Fetch active newsletters first (`/newsletters/?filter=status:active`) and pass a verified `slug` from that list.","Confirm the newsletter is in `active` status, not archived.","Pass the newsletter `slug` (not id or display name) as the `newsletter` param.","If no active newsletter exists, create/reactivate one before publishing with email."],"exampleFix":"// before\nawait api.posts.edit({id, status: 'published'}, {newsletter: 'Weekly-Digest'}); // wrong case / archived\n\n// after\nconst active = await api.newsletters.browse({filter: 'status:active'});\nconst slug = active.newsletters[0].slug;\nawait api.posts.edit({id, status: 'published'}, {newsletter: slug});","handlingStrategy":"validation","validationCode":"async function resolveActiveNewsletterSlug(api, requestedSlug) {\n  const res = await api.newsletters.browse({filter: 'status:active'});\n  const slugs = res.newsletters.map(n => n.slug);\n  if (!slugs.includes(requestedSlug)) throw new Error(`Newsletter '${requestedSlug}' is not active; available: ${slugs.join(', ')}`);\n  return requestedSlug;\n}","typeGuard":"const isActiveNewsletterRef = (n) => n && typeof n.slug === 'string' && n.status === 'active';","tryCatchPattern":"try {\n  await api.posts.edit({id, status: 'published'}, {newsletter: slug});\n} catch (err) {\n  if (err.type === 'BadRequestError' && /doesn't match any active newsletter/i.test(err.message)) refreshNewsletters();\n  else throw err;\n}","preventionTips":["Always pass a slug sourced from a fresh active-newsletter list.","Re-fetch newsletters before publish if the page has been open a while (newsletters may be archived).","Pass the slug, never the id or display name."],"tags":["newsletter","publishing","post","validation","email"],"backgroundTag":null,"analyzedSha":"47d8b0e2ad2fd4757d3bc45f46c3ac165ff8a1fe","analyzedAt":"2026-08-13T01:25:26.651Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}