๐Ÿšจ WDYBTW: Check comment widgets reading post.excerpt from Members API

What did you break this week, week of 2026-09-17

๐Ÿšจ WDYBTW: Check comment widgets reading post.excerpt from Members API

The most consequential change this week is merged: Members API comment endpoints called with include=post no longer return post.excerpt on any post, so custom comment widgets that read it must fetch the excerpt from the Content API instead. The same merged fix reverts the post access check on comment reads, while like and dislike now return 403 for members without access to a gated post. Other merged changes alter newsletter email HTML (the Name row is dropped for members without a name), add a metafield_change_event type to the member activity feed, enforce SVG sanitization with 415 errors on Admin API uploads, and defer paid-subscription events until Stripe subscriptions become active. Among open pull requests, the one to watch is a change that narrows the member resolved from a session cookie, which may drop newsletters and email_suppression from /members/api/member/.

Contents

Merged

Endpoint response shapes

๐Ÿ› Fixed comments on gated posts being hidden from readers without access ยท Merged 2026-09-17 ยท acburdine

Impact: high ยท Confidence: high ยท ๐Ÿšจ Breaking

The Members API comments endpoints no longer return post.excerpt when called with include=post, on any post (free or paid). Admin API comment responses still include it.

  • What changed: Comment serializer mapper only sets post.excerpt (custom_excerpt or first 500 chars of plaintext) when !isPublicRequest. /members/api/comments/?include=post now returns post with id, uuid, title, url, feature_image only.
  • Who is affected: Custom comment widgets, themes or external clients that read post.excerpt from Members API comment responses (browse, single comment, replies with include=post).
  • What to check: Search your code for post.excerpt read from /members/api/comments responses and fetch the excerpt from the Content API posts endpoint instead. Admin API consumers of /ghost/api/admin/comments are unaffected.
  • Medium, Permissions & endpoint behaviour: Per the description, the post access check added in #30402 for Members API comment reads is reverted, so comments on gated posts are readable again by visitors without access. Like and dislike now require post access and return 403 without it; unlike, undislike, edit and delete of own comments do not check post access. These service changes are not in the shown diff.

Medium Impact Changes

  • Improved thumbnail validation of svgs ยท Merged 2026-09-21 ยท Permissions & endpoint behaviour ยท Admin API image and media uploads now run SVG sanitization based on the declared content type as well as the file extension. A file declared as SVG that does not parse as valid SVG is rejected with a 415 error.
  • Removed subscriber name fields when no name is provided ยท Merged 2026-09-21 ยท Web & email rendering, Endpoint response shapes ยท Newsletter emails now drop the subscriber Name row entirely, in both HTML and plaintext, when the member has no name. Previously the row was hidden with CSS, and plaintext showed "Name: not provided".
  • Fixed incomplete subscriptions being counted as paid conversions ยท Merged 2026-09-17 ยท Other ยท Ghost no longer records a paid-subscription 'created' event, conversion attribution or offer redemption for Stripe subscriptions in incomplete or incomplete_expired status. These are recorded once, when the subscription becomes active or trialing, so activity, MRR and conversion data exposed through the Admin API changes in content and timing.
  • Added member custom field changes to the member activity feed ยท Merged 2026-09-17 ยท Endpoint response shapes, Other ยท The Admin API member activity feed can now return a new event type, metafield_change_event, for every write to a member's custom fields. Writers include Portal, Admin, Admin API integrations, imports and checkout.

Low Impact Changes

  • ๐Ÿ› Fixed footer action icons wrapping in Firefox ยท Merged 2026-09-17 ยท Web & email rendering ยท The newsletter email partial for feedback and comment buttons no longer adds an inline display: inline-block style to its table cell, so the cells use native table-cell layout. The rendered newsletter HTML changes slightly. No markup, classes or links change.
  • Fixed the API pipeline cloning its cache adapter ยท Merged 2026-09-18 ยท Other ยท The API pipeline no longer deep-clones a controller's cache adapter. Cache adapters that keep state in #private fields, such as memory-ttl, now work as API response caches instead of making every cached request return a 500. reset() calls from services now reach the cache that actually serves requests.
  • Replaced express-queue with an in-house request queue ยท Merged 2026-09-17 ยท Other ยท The optional request-queue middleware now uses in-house code instead of express-queue. API responses do not change. Request logs now record client disconnects as 499 and add a queue wait time. Startup now rejects a concurrencyLimit that is not a positive integer.

Open

Medium Impact Changes

  • Added newsletter retry eligibility to Core ยท Open ยท Permissions & endpoint behaviour, Endpoint response shapes ยท Retrying a failed newsletter email is now rejected with 400 when any batch is still 'submitting', meaning the delivery outcome is unknown. Eligibility is also re-read from the database instead of trusting the caller's model.
  • Fixed free members subscribing to paid-only newsletters ยท Open ยท Permissions & endpoint behaviour, Endpoint response shapes ยท Members API self-service endpoints now silently drop newsletters whose visibility is not 'members' when the member is, or will be, free. The request still succeeds, but the paid-only subscription is not recorded.
  • Added agent payments for premium markdown URLs ยท Open ยท Endpoint response shapes, Web & email rendering, Permissions & endpoint behaviour ยท Admin API settings responses now include three new site-group settings for agent payments. The Admin config response adds a machinePayments labs flag.
  • โœจ Added site-level robots.txt editing in Labs ยท Open ยท Web & email rendering, Endpoint response shapes ยท /robots.txt precedence changes: when the robots_txt setting is non-blank, Ghost serves it instead of the theme's robots.txt. Private-site handling is unchanged.
  • ๐Ÿ› Fixed template view render bug with `.` filenames ยท Open ยท Web & email rendering ยท The frontend renderer now always appends .hbs to the selected template name before calling res.render, unless the path is absolute. Theme templates whose filenames contain extra dots (e.g. custom-foo.bar.hbs) now render instead of failing.
  • Fixed unpaid asynchronous donations being recorded ยท Open ยท Other, Endpoint response shapes ยท Donations paid with delayed methods such as SEPA or bank transfer are now recorded only when Stripe reports the payment as paid, not at checkout completion. Retried Stripe webhooks for the same checkout session no longer create duplicate donations or staff emails.

Low Impact Changes

  • Added host-managed upgrade adapter support ยท Open ยท Permissions & endpoint behaviour, Endpoint response shapes, Other ยท Three new Admin API routes for host-managed upgrades are added. They are restricted to Owner and Administrator staff, and integration (Admin API key) tokens are not granted the new permissions.
  • Added concurrent newsletter preparation from an upfront recipient sweep ยท Open ยท Other ยท Newsletter batch preparation now selects every recipient ID and content segment in one UNION ALL query, then writes batches with up to two concurrent workers. It adds a new config key; no API, webhook or template output changes.
  • Added nullable newsletter recipient accounting columns ยท Open ยท Endpoint response shapes ยท Seven nullable columns are added to the emails and email_batches tables. The four emails columns are explicitly stripped from Admin API email, post.email and activity-feed output. The three email_batches columns are not stripped in this diff and may appear in email batch responses.
  • ๐ŸŽจ Added user-editable alt text for the Product card. ยท Open ยท Endpoint response shapes, Web & email rendering ยท The product card node in a post's lexical JSON gains a new string property, productImageAlt, defaulting to an empty string. Older posts without the key still load. This shows up in Admin API post and page lexical output and can be set by API clients that write lexical.
  • ๐Ÿ› Fixed escaping of links in the comment reply email ยท Open ยท Web & email rendering ยท The comment reply notification email now HTML-escapes post titles, URLs and email addresses in its links. Output for ordinary values is reported as byte-identical; only values containing HTML characters render differently, now as text instead of markup.

Drafts

Endpoint response shapes

Impact: high ยท Confidence: medium ยท ๐Ÿšจ Breaking

The session-resolved member may now omit newsletters, labels, email_suppression, attribution and current_subscription. If GET /members/api/member/ builds its response from getMemberDataFromSession (the diff does not show this), Portal and custom clients reading newsletters or email_suppression there would get undefined.

  • What changed: getMemberIdentityDataFromTransientId now calls readForSession, not read. That drops newsletters, labels, currentSubscription, member attribution and email_suppression. unsubscribe_url and subscriptions[].attribution are kept.
  • Who is affected: Portal forks and custom front-end or Members API clients that read the session member's JSON, especially newsletters, email_suppression, labels or attribution from /members/api/member/.
  • What to check: With a signed-in member cookie, call GET /members/api/member/ before and after this change. Confirm newsletters, email_suppression and subscribed are still present and correct. The PR says this endpoint uses read, but the middleware is not in the diff.
  • Medium, Sessions & cookies: The member that a members session cookie resolves to (req.member, getMemberDataFromSession, and the source for identity and entitlement tokens) is now a narrower object. Cookie names and the transient_id lookup are unchanged.
  • Low, Web & email rendering: Theme-facing @member should be unchanged. The fixed field list does not include the dropped relations, and subscription attribution and comped or gift synthetic subscriptions are preserved.

Medium Impact Changes

  • Media library ยท Open (draft) ยท Permissions & endpoint behaviour, Other, Endpoint response shapes ยท New Admin API media library endpoints are added under /ghost/api/admin/media. Integration API keys can now reach them, but the new permissions are only granted to staff roles.

Low Impact Changes

  • โœจ Released self-serve site exports ยท Open (draft) ยท Permissions & endpoint behaviour ยท The Admin API endpoints GET /exports/download and POST /exports are no longer gated behind the selfServeArchives Labs flag. They now respond on all sites instead of returning 404 when the flag was off.
  • Added the app installations table and Admin API ยท Open (draft) ยท Permissions & endpoint behaviour, Endpoint response shapes ยท Three new Admin API routes for app installations were added. They sit behind the private 'apps' labs flag and a table that only exists in development and test databases, so production sites answer 404. Only Administrators and the Owner get permissions; integrations get none.
  • Added runtime Zod validation to API framework ยท Open (draft) ยท Other ยท The api-framework pipeline can now run Zod schemas on API methods that declare one. No existing endpoint declares a schema in this PR, so current Admin, Content and Members API behaviour is unchanged.
  • Improved date handling cost when fetching rows on large sites ยท Open (draft) ยท Other ยท Internal performance change to how the model layer normalises dateTime columns on read and write. Admin, Content and Members API date fields such as created_at, updated_at and published_at should keep the same values and second precision.