Skip to content

🐛 Fixed periodic host limits in Admin - #29837

Open
betschki wants to merge 7 commits into
TryGhost:mainfrom
magicpages:fix/admin-periodic-limits
Open

🐛 Fixed periodic host limits in Admin#29837
betschki wants to merge 7 commits into
TryGhost:mainfrom
magicpages:fix/admin-periodic-limits

Conversation

@betschki

@betschki betschki commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

Admin's limit service loaded limits without the subscription argument that @tryghost/limit-service requires for periodic limits, so any configured maxPeriodic limit threw an IncorrectUsageError in the browser. Loading stops at the first limit that can't be built, so a site with an emails limit ended up with no limits registered at all, and the rejection surfaced in the editor's publish flow.

  • passes the subscription through, resolved from hostSettings the same way the server does
  • adds a client-side count query for emails, since the default one counts recipients via knex
  • skips the emails check for authors and contributors, who can't browse emails, matching how the members limit is already handled
  • tolerates a limit that can't be built instead of leaving Admin with none

Got some code for us? Awesome 🎊!

Please take a minute to explain the change you're making:

  • Why are you making it?
  • What does it do?
  • Why is this something Ghost users or developers need?

Please check your PR against these items:

  • I've read and followed the Contributor Guide
  • I've explained my change
  • I've written an automated test to prove my change works

We appreciate your contribution! 🙏

no ref

Admin's limit service loaded limits without the `subscription` argument that
@tryghost/limit-service requires for periodic limits, so any configured
maxPeriodic limit threw an IncorrectUsageError in the browser. Loading stops at
the first limit that can't be built, so a site with an emails limit ended up
with no limits registered at all, and the rejection surfaced in the editor's
publish flow.

- passes the subscription through, resolved from hostSettings the same way the
  server does
- adds a client-side count query for emails, since the default one counts
  recipients via knex
- skips the emails check for authors and contributors, who can't browse emails,
  matching how the members limit is already handled
- tolerates a limit that can't be built instead of leaving Admin with none
@coderabbitai

coderabbitai Bot commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

The limits service now registers subscription-aware monthly limits and filters periodic limits when subscription data is unavailable. Email limits use a browser-compatible query that sums recipients created after the period start. Publishing skips checks for authors and contributors and handles an absent limiter. Email verification remains independently evaluated. Tests cover subscription handling, count aggregation, filtering, empty results, Sinon cleanup, and the account-review hold.

Suggested reviewers: 9larsons, kevinansfield

🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly identifies the primary change: fixing periodic host-limit handling in Admin.
Description check ✅ Passed The description directly explains the limit-service fix, email-count query, role handling, and continued limit loading.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@apps/ember-admin/app/services/limit.js`:
- Around line 79-86: Update loadLimits and its Object.keys(limits).forEach
registration flow so an IncorrectUsageError from a missing subscription for a
<name>.maxPeriodic limit is handled during iteration, allowing later valid
limits to register. Preserve propagation of other errors and add or update
coverage with an invalid periodic limit followed by a valid non-periodic limit.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 18be5678-060a-46e6-b66e-08c90c0caf10

📥 Commits

Reviewing files that changed from the base of the PR and between f318505 and 47fe2a8.

📒 Files selected for processing (3)
  • apps/ember-admin/app/services/limit.js
  • apps/ember-admin/app/utils/publish-options.js
  • apps/ember-admin/tests/unit/services/limit-test.js

Comment thread apps/ember-admin/app/services/limit.js Outdated
no ref

loadLimits() registers limits in a forEach, so a periodic limit that can't be
built stops the loop and drops every limit declared after it. Catching the error
afterwards kept Admin running but still lost those later limits.

Filters periodic limits out when there is no subscription to build them from, so
the rest register as normal.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@apps/ember-admin/app/services/limit.js`:
- Around line 69-71: Update the subscription construction in the limit-loading
flow before usableLimits() is called so hostSettings.subscription is only
created when its start value exists. Ensure missing subscription.start produces
no subscription object, allowing usableLimits() to filter out periodic limits
and preventing getEmailsCount() from receiving an undefined startDate.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 0aa595e1-dd1d-44f6-b34e-cea460432ffe

📥 Commits

Reviewing files that changed from the base of the PR and between 47fe2a8 and 96f33e0.

📒 Files selected for processing (2)
  • apps/ember-admin/app/services/limit.js
  • apps/ember-admin/tests/unit/services/limit-test.js
🚧 Files skipped from review as they are similar to previous changes (1)
  • apps/ember-admin/tests/unit/services/limit-test.js

Comment thread apps/ember-admin/app/services/limit.js
no ref

A hostSettings.subscription with no start built a subscription object anyway,
which passed the periodic-limit filter and then threw on the missing start date.
The emails count query would have received an undefined start too.

@9larsons 9larsons left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There’s one performance concern in the new browser-side email count query.

Comment thread apps/ember-admin/app/services/limit.js Outdated
no ref

The emails browse response carries the full html, plaintext and source of every
record, and the query is awaited while the publish options load. Selecting id
and email_count keeps the count and drops the bodies.

@9larsons 9larsons left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

@nx-cloud

nx-cloud Bot commented Aug 10, 2026

Copy link
Copy Markdown

🤖 Nx Cloud AI Fix

Ensure the fix-ci command is configured to always run in your CI pipeline to get automatic fixes in future runs. For more information, please see https://nx.dev/ci/features/self-healing-ci


View your CI Pipeline Execution ↗ for commit 721d5ed

Command Status Duration Result
nx run @tryghost/admin:test:acceptance ✅ Succeeded 8m View ↗
nx run-many -t test:unit -p @tryghost/admin ✅ Succeeded 4m 3s View ↗
nx run ghost-admin:test ✅ Succeeded 3m 4s View ↗
nx run @tryghost/admin:build ✅ Succeeded 1m 52s View ↗
nx run ghost-monorepo:lint:boundaries ✅ Succeeded 22s View ↗
nx run-many -t lint -p ghost-admin,@tryghost/ad... ✅ Succeeded 1m 25s View ↗
nx run-many --target=build --projects=tag:publi... ✅ Succeeded 1s View ↗

💡 Verify your cache is correct by running tasks in a sandbox. Read docs ↗


☁️ Nx Cloud last updated this comment at 2026-08-10 22:36:02 UTC

@9larsons
9larsons enabled auto-merge (squash) August 10, 2026 22:30

@9larsons 9larsons left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

D'oh, one more.

@9larsons 9larsons left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One additional interaction surfaced in a second pass.

Comment thread apps/ember-admin/app/utils/publish-options.js Outdated
@codecov

codecov Bot commented Aug 10, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 94.11765% with 1 line in your changes missing coverage. Please review.
✅ Project coverage is 75.45%. Comparing base (5406605) to head (721d5ed).
⚠️ Report is 37 commits behind head on main.

Files with missing lines Patch % Lines
apps/ember-admin/app/utils/publish-options.js 0.00% 0 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main   #29837      +/-   ##
==========================================
+ Coverage   75.40%   75.45%   +0.04%     
==========================================
  Files        1606     1606              
  Lines      140381   140397      +16     
  Branches    17389    17406      +17     
==========================================
+ Hits       105860   105931      +71     
+ Misses      33444    33418      -26     
+ Partials     1077     1048      -29     
Flag Coverage Δ
admin-tests 56.03% <94.11%> (+0.05%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

no ref

With periodic email limits now registering, an admin or editor under their limit
took the first branch and skipped the verification check, so the publish UI
offered email during an account-review hold and the rejection only came back from
the server. The server applies both in this order; this now mirrors it, keeping
the limit error ahead of the hold.
auto-merge was automatically disabled August 11, 2026 06:14

Head branch was pushed to by a user without write access

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@apps/ember-admin/tests/acceptance/editor/publish-flow-test.js`:
- Around line 694-709: Update the publish-flow test setup around the `/emails/`
handler and its warning assertion to capture or inspect the request made by
`LimitsService.getEmailsCount`. Assert that the email-count query reaches the
endpoint with the expected filter, fields, and limit parameters before asserting
the warning, ensuring the emails limiter path is exercised.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 62844348-1e18-4f9b-85e7-d03c9949ce79

📥 Commits

Reviewing files that changed from the base of the PR and between 721d5ed and 5441e4f.

📒 Files selected for processing (2)
  • apps/ember-admin/app/utils/publish-options.js
  • apps/ember-admin/tests/acceptance/editor/publish-flow-test.js
🚧 Files skipped from review as they are similar to previous changes (1)
  • apps/ember-admin/app/utils/publish-options.js

Comment thread apps/ember-admin/tests/acceptance/editor/publish-flow-test.js
no ref

The test returned an empty emails response but never checked the request was
made, so it would have passed on the verification hold alone with the emails
limiter never registering.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants