Validation Error, Cannot List Tiers — persisting in 5.23 & 5.24

Just upgraded one of my Ghost installs to 5.23, and it’s still throwing the error that’s mentioned in this closed thread. The fix introduced in the 5.22 series doesn’t seem to have the job for this install, at least.

Any advice?

Same issue here on 5.23

1 Like

I believe this is to do with having a tier with a price of 0.

It would be good to confirm if this is the case.

The site in question was connected to Stripe, but no paid tiers had been set up. The free tier was the only option.

Indeed. I only have free tiers. Can’t get to the site to edit it though because of the error.

1 Like

OK - it sounds like there’s a state that tiers can be in that isn’t accounted for.

There’s not a lot of information here to go on though - is anyone able to pull the full error from their ghost logs, and also grab the data out of the products table in the database?

This the sort of thing?

[2022-11-24 06:05:41] ERROR "GET /ghost/api/content/tiers/?key=c2122330deaa9b4de09a074168&limit=all&include=monthly_price,yearly_price,benefits" 422 37ms

NAME: ValidationError
MESSAGE: Tier prices must be an integer.

level: normal

ValidationError: Tier prices must be an integer.
    at validateMonthlyPrice (/var/www/ghost/versions/5.23.0/node_modules/@tryghost/tiers/lib/Tier.js:423:15)
    at Function.create (/var/www/ghost/versions/5.23.0/node_modules/@tryghost/tiers/lib/Tier.js:258:28)
    at TierRepository.getAll (/var/www/ghost/versions/5.23.0/core/server/services/tiers/TierRepository.js:62:37)
    at async TiersAPI.browse (/var/www/ghost/versions/5.23.0/node_modules/@tryghost/tiers/lib/TiersAPI.js:50:23)
    at async Object.query (/var/www/ghost/versions/5.23.0/core/server/api/endpoints/tiers-public.js:17:26)
    at async /var/www/ghost/versions/5.23.0/node_modules/@tryghost/api-framework/lib/http.js:64:28

I suspect that grabbing the products data is beyond my limited abilities.

My logs show the exact same.

NAME: ValidationError
MESSAGE: Tier prices must be an integer.

level: normal

ValidationError: Tier prices must be an integer.
    at validateMonthlyPrice (/var/www/ghost/versions/5.23.0/node_modules/@tryghost/tiers/lib/Tier.js:423:15)
    at Function.create (/var/www/ghost/versions/5.23.0/node_modules/@tryghost/tiers/lib/Tier.js:258:28)
    at TierRepository.getAll (/var/www/ghost/versions/5.23.0/core/server/services/tiers/TierRepository.js:62:37)
    at async TiersAPI.browse (/var/www/ghost/versions/5.23.0/node_modules/@tryghost/tiers/lib/TiersAPI.js:50:23)
    at async Object.query (/var/www/ghost/versions/5.23.0/core/server/api/endpoints/tiers-public.js:17:26)
    at async /var/www/ghost/versions/5.23.0/node_modules/@tryghost/api-framework/lib/http.js:64:28
mysql> select * from products;
+--------------------------+--------------------+--------------------------+---------------------+---------------------+-------------+--------------------------+--------------------------+------+--------+------------------+------------+------------+---------------+--------------+----------+
| id                       | name               | slug                     | created_at          | updated_at          | description | monthly_price_id         | yearly_price_id          | type | active | welcome_page_url | visibility | trial_days | monthly_price | yearly_price | currency |
+--------------------------+--------------------+--------------------------+---------------------+---------------------+-------------+--------------------------+--------------------------+------+--------+------------------+------------+------------+---------------+--------------+----------+
| 60932dcb761f870f5340bee3 | Ghost Subscription | ghost-subscription       | 2021-05-05 23:44:11 | 2022-08-27 13:07:04 | NULL        | 62d970d95837ceff76fb0e5f | 62d970da5837ceff76fb0e60 | paid |      1 | /                | public     |          0 |             0 |            0 | usd      |
| 6220a70ca633cc1132c35a05 | Free               | 6220a70ca633cc1132c35a05 | 2022-03-03 11:31:24 | NULL                | NULL        | NULL                     | NULL                     | free |      1 | /                | public     |          0 |          NULL |         NULL | NULL     |
+--------------------------+--------------------+--------------------------+---------------------+---------------------+-------------+--------------------------+--------------------------+------+--------+------------------+------------+------------+---------------+--------------+----------+
2 rows in set (0.00 sec)

mysql>

Not a surprise, as this is still clearly being investigated - but it’s not fixed in 5.24.

Hey everyone, I am sorry for the delay here.

We’ve been investigating and trying to understand the problem - I know that it’s a real pain as it’s blocking admin access.

The default tiers included with Ghost include a free tier, and a paid tier with prices of $5 monthly and $50 annually. These paid tiers should not be possible to set to have 0 price.

At some point over the last year, there was a brief period where validation broke, and it was possible to set the price of a paid tier to 0 - which is not a valid value.

Recent changes to refactor Ghost’s payment handling and make it super robust have resulted in sites with these 0 prices falling foul of the new validation.

We are going to get a fix for this into the next Friday release, but in the meantime, you can resolve the issue by fixing the bad data in the database.

To do this you need to:

  1. Connect to your database. This should be MySQL8 in all cases now. The credentials for your database will be in you config.production.json file in the root of your Ghost install & look like this:
        "client": "mysql",
        "connection": {
          "host": "127.0.0.1",
          "port": 3306,
          "user": "myusername",
          "password": "mysecretpassword",
          "database": "mydatabasename"
        }
    },

The connection string will be mysql -u myusername -p mydatabasename, which will then ask you to enter the password.

  1. Once connected, you can take a quick look at your data by running select * from products;
  2. To fix any broken values, run the following two queries. They only change values that are 0:

UPDATE products SET monthly_price = 500 WHERE monthly_price = 0;

then

UPDATE products SET yearly_price = 5000 WHERE yearly_price = 0;

This will change the tiers back to their default values, and allow you to access the admin panel to make further amends to your setup.

1 Like

That worked. Thanks very much!