‘Posts’ page gives 500

Hi all,

For a while I have had an issue with my 1.x installation of Ghost and now wanted to migrate to 2.25.x. Interestingly the same problem appears: I cannot manage my posts. The browser just displays a 500 error (plus a tumbleweed).

That is a fresh install of Ghost 2 with the latest source from just a few days ago. All I did was export the data of my old installation and import it into the new one (via labs). Does anybody see anything wrong with my posts?

Old ghost: blog.kloetzl.info
New ghost: blog2.kloetzl.info (no TLS)

Node does not give any hints on what might be wrong. The browser console gives a JSON error, about some unterminated string literal but is otherwise unhelpful.

I appreciate any help!

Hi @kloetzl :wave: It’s hard to tell by just looking at the blog itself :upside_down_face: Would be helpful to investigate what the server logs say when this error appears (usually can be found in /content/logs/). Let me know if you found anything interesting there and if you could paste it here would be easier to get to the bottom of it :slight_smile:

Hi,

Thanks for your help. The Ghost v2 instance has just one error in the logs. At the bottom is the error message that appears in the browser console.

    {
    "name": "Log",
    "hostname": "sirius.uberspace.de",
    "pid": 4704,
    "level": 50,
    "req": {
        "meta": {
            "requestId": "0212a6a0-ac62-11e9-b6b8-4b1926406d90",
            "userId": null
        },
        "url": "/users/me/?include=roles",
        "method": "GET",
        "originalUrl": "/ghost/api/v2/admin/users/me/?include=roles",
        "params": {},
        "headers": {
            "host": "localhost:62448",
            "user-agent": "Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Firefox/68.0",
            "accept": "application/json, text/javascript, */*; q=0.01",
            "accept-language": "en-US,en;q=0.5",
            "accept-encoding": "gzip, deflate",
            "referer": "http://blog2.kloetzl.info/ghost/",
            "content-type": "application/json; charset=UTF-8",
            "x-ghost-version": "2.25",
            "app-pragma": "no-cache",
            "x-requested-with": "XMLHttpRequest",
            "dnt": "1",
            "x-forwarded-proto": "http",
            "x-forwarded-port": "80",
            "x-forwarded-for": "141.5.9.188, 141.5.9.188",
            "x-forwarded-host": "blog2.kloetzl.info",
            "x-forwarded-server": "kloetzl.sirius.uberspace.de",
            "connection": "Keep-Alive"
        },
        "query": {
            "include": "roles"
        }
    },
    "res": {
        "_headers": {
            "x-powered-by": "Express",
            "cache-control": "no-cache, private, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0",
            "content-type": "application/json; charset=utf-8",
            "content-length": "321",
            "etag": "W/\"141-X35vf/6EyNzbfO01HVqKgP8R7ps\"",
            "vary": "Accept-Encoding"
        },
        "statusCode": 403,
        "responseTime": "11ms"
    },
    "err": {
        "id": "0213df20-ac62-11e9-b6b8-4b1926406d90",
        "domain": "http://blog2.kloetzl.info/",
        "code": null,
        "name": "NoPermissionError",
        "statusCode": 403,
        "level": "normal",
        "message": "Authorization failed",
        "context": "\"Unable to determine the authenticated user or integration. Check that cookies are being passed through if using session authentication.\"",
        "stack": "NoPermissionError: Authorization failed\n    at new NoPermissionError (/home/kloetzl/ghost2/node_modules/ghost-ignition/lib/errors/index.js:114:23)\n    at authorizeAdminApi (/home/kloetzl/ghost2/core/server/services/auth/authorize.js:76:25)\n    at Layer.handle [as handle_request] (/home/kloetzl/ghost2/node_modules/express/lib/router/layer.js:95:5)\n    at next (/home/kloetzl/ghost2/node_modules/express/lib/router/route.js:137:13)\n    at authenticate (/home/kloetzl/ghost2/core/server/services/auth/session/middleware.js:103:16)\n    at Layer.handle [as handle_request] (/home/kloetzl/ghost2/node_modules/express/lib/router/layer.js:95:5)\n    at next (/home/kloetzl/ghost2/node_modules/express/lib/router/route.js:137:13)\n    at authenticate (/home/kloetzl/ghost2/core/server/services/auth/api-key/admin.js:42:16)\n    at Layer.handle [as handle_request] (/home/kloetzl/ghost2/node_modules/express/lib/router/layer.js:95:5)\n    at next (/home/kloetzl/ghost2/node_modules/express/lib/router/route.js:137:13)\n    at Route.dispatch (/home/kloetzl/ghost2/node_modules/express/lib/router/route.js:112:3)\n    at Layer.handle [as handle_request] (/home/kloetzl/ghost2/node_modules/express/lib/router/layer.js:95:5)\n    at /home/kloetzl/ghost2/node_modules/express/lib/router/index.js:281:22\n    at param (/home/kloetzl/ghost2/node_modules/express/lib/router/index.js:354:14)\n    at param (/home/kloetzl/ghost2/node_modules/express/lib/router/index.js:365:14)\n    at Function.process_params (/home/kloetzl/ghost2/node_modules/express/lib/router/index.js:410:3)\n    at next (/home/kloetzl/ghost2/node_modules/express/lib/router/index.js:275:10)\n    at Function.handle (/home/kloetzl/ghost2/node_modules/express/lib/router/index.js:174:3)\n    at router (/home/kloetzl/ghost2/node_modules/express/lib/router/index.js:47:12)\n    at Layer.handle [as handle_request] (/home/kloetzl/ghost2/node_modules/express/lib/router/layer.js:95:5)\n    at trim_prefix (/home/kloetzl/ghost2/node_modules/express/lib/router/index.js:317:13)\n    at /home/kloetzl/ghost2/node_modules/express/lib/router/index.js:284:7"
    },
    "msg": "Authorization failed",
    "time": "2019-07-22T09:20:55.323Z",
    "v": 0
}

Browser error:

Error while processing route: posts JSON.parse: unterminated string literal at line 1 column 265 of the JSON data deserialize@http://blog2.kloetzl.info/ghost/assets/ghost.min-42b2778d11b38793c166227bdf1b2d83.js:1896:13
applyTransforms/<@http://blog2.kloetzl.info/ghost/assets/vendor.min-f46d38749a8eedcd575bf79c4d1ba4e4.js:8443:8
eachTransformedAttribute/<@http://blog2.kloetzl.info/ghost/assets/vendor.min-f46d38749a8eedcd575bf79c4d1ba4e4.js:7911:245
eachTransformedAttribute@http://blog2.kloetzl.info/ghost/assets/vendor.min-f46d38749a8eedcd575bf79c4d1ba4e4.js:7911:227
applyTransforms@http://blog2.kloetzl.info/ghost/assets/vendor.min-f46d38749a8eedcd575bf79c4d1ba4e4.js:8442:10
normalize@http://blog2.kloetzl.info/ghost/assets/vendor.min-f46d38749a8eedcd575bf79c4d1ba4e4.js:8456:265
normalize@http://blog2.kloetzl.info/ghost/assets/vendor.min-f46d38749a8eedcd575bf79c4d1ba4e4.js:8368:55
n@http://blog2.kloetzl.info/ghost/assets/vendor.min-f46d38749a8eedcd575bf79c4d1ba4e4.js:2561:9
_normalizePolymorphicRecord@http://blog2.kloetzl.info/ghost/assets/vendor.min-f46d38749a8eedcd575bf79c4d1ba4e4.js:8495:68
_normalizeArray/<@http://blog2.kloetzl.info/ghost/assets/vendor.min-f46d38749a8eedcd575bf79c4d1ba4e4.js:8492:67
_normalizeArray@http://blog2.kloetzl.info/ghost/assets/vendor.min-f46d38749a8eedcd575bf79c4d1ba4e4.js:8492:27
_normalizeResponse@http://blog2.kloetzl.info/ghost/assets/vendor.min-f46d38749a8eedcd575bf79c4d1ba4e4.js:8501:66
normalizeArrayResponse@http://blog2.kloetzl.info/ghost/assets/vendor.min-f46d38749a8eedcd575bf79c4d1ba4e4.js:8452:1180
normalizeArrayResponse@http://blog2.kloetzl.info/ghost/assets/ghost.min-42b2778d11b38793c166227bdf1b2d83.js:1398:105
n@http://blog2.kloetzl.info/ghost/assets/vendor.min-f46d38749a8eedcd575bf79c4d1ba4e4.js:2561:9
normalizeQueryResponse@http://blog2.kloetzl.info/ghost/assets/vendor.min-f46d38749a8eedcd575bf79c4d1ba4e4.js:8452:661
normalizeResponse@http://blog2.kloetzl.info/ghost/assets/vendor.min-f46d38749a8eedcd575bf79c4d1ba4e4.js:8449:25
ge@http://blog2.kloetzl.info/ghost/assets/vendor.min-f46d38749a8eedcd575bf79c4d1ba4e4.js:7932:65
_query/</<@http://blog2.kloetzl.info/ghost/assets/vendor.min-f46d38749a8eedcd575bf79c4d1ba4e4.js:8133:326
f@http://blog2.kloetzl.info/ghost/assets/vendor.min-f46d38749a8eedcd575bf79c4d1ba4e4.js:4598:17
_@http://blog2.kloetzl.info/ghost/assets/vendor.min-f46d38749a8eedcd575bf79c4d1ba4e4.js:4608:12
W@http://blog2.kloetzl.info/ghost/assets/vendor.min-f46d38749a8eedcd575bf79c4d1ba4e4.js:4606:128
M</t.invoke@http://blog2.kloetzl.info/ghost/assets/vendor.min-f46d38749a8eedcd575bf79c4d1ba4e4.js:4137:163
M</t.flush@http://blog2.kloetzl.info/ghost/assets/vendor.min-f46d38749a8eedcd575bf79c4d1ba4e4.js:4129:74
z</t.flush@http://blog2.kloetzl.info/ghost/assets/vendor.min-f46d38749a8eedcd575bf79c4d1ba4e4.js:4142:358
F</n._end@http://blog2.kloetzl.info/ghost/assets/vendor.min-f46d38749a8eedcd575bf79c4d1ba4e4.js:4204:9
F</n.end@http://blog2.kloetzl.info/ghost/assets/vendor.min-f46d38749a8eedcd575bf79c4d1ba4e4.js:4159:230
F</n._run@http://blog2.kloetzl.info/ghost/assets/vendor.min-f46d38749a8eedcd575bf79c4d1ba4e4.js:4206:118
F</n._join@http://blog2.kloetzl.info/ghost/assets/vendor.min-f46d38749a8eedcd575bf79c4d1ba4e4.js:4205:246
F</n.join@http://blog2.kloetzl.info/ghost/assets/vendor.min-f46d38749a8eedcd575bf79c4d1ba4e4.js:4170:13
d@http://blog2.kloetzl.info/ghost/assets/vendor.min-f46d38749a8eedcd575bf79c4d1ba4e4.js:3023:28
_makeRequest/c</<@http://blog2.kloetzl.info/ghost/assets/vendor.min-f46d38749a8eedcd575bf79c4d1ba4e4.js:7174:11
p@http://blog2.kloetzl.info/ghost/assets/vendor.min-f46d38749a8eedcd575bf79c4d1ba4e4.js:558:118
fireWith@http://blog2.kloetzl.info/ghost/assets/vendor.min-f46d38749a8eedcd575bf79c4d1ba4e4.js:559:694
W@http://blog2.kloetzl.info/ghost/assets/vendor.min-f46d38749a8eedcd575bf79c4d1ba4e4.js:839:443
n/<@http://blog2.kloetzl.info/ghost/assets/vendor.min-f46d38749a8eedcd575bf79c4d1ba4e4.js:849:206
2 vendor.min-f46d38749a8eedcd575bf79c4d1ba4e4.js:2225:108

The server error looks like a regular Authorization error which happens when you issue first requests before logging into ghost.

The frontend error looks a little bit more interesting and points to having malformatted JSON in the response. Can you run a JSON validator (like this one) on the response body of the GET /posts/ requests after which frontend throws this error?

So I had a look at the JSON and it is valid, as far as I can tell. You can have a look yourself here.

What I find curious, is that basically, the blog still works. It can display all posts no problem. Just this one admin page is broken.

Also, the issue is not browser specific. It happens in both Firefox and Chrome.

Hm… It’s a tricky one to debug indeed. Even though the JSON you’ve mentioned looks valid I’m still convinced it has to do with the data returned from the server. Would be useful to somehow narrow it down to single ‘bad apple’ and go from there. From the above information, my assumption is that it breaks after fetching first 30 posts to display on “posts” and unterminated string literal at line 1 column 265 gives a clue it’s probably one of the first posts in the response. Are you able to modify Koenig Demo Post in the db to become page temporarily (UPDATE posts SET page=1 WHERE id="5d2b494626255d7b668e9ba7") and see if the “pages” page breaks? This would give a clue to search for JSON breaking symbols in that post :thinking: if that doesn’t help could try on few more posts and then move on to do more investigation.

With a lot of updating pages I got closer to the issue. The post “Welcome to Ghost” comes with a JSON attribute “mobiledoc” which itself contains JSON. That latter JSON is invalid.

"{\"version\":\"0.3.1\",\"atoms\":[],\"cards\":[],\"markups\":[[\"strong\"],[\"a\",[\"href\",\"https://ghost.org/downloads/\"]],[\"a\",[\"href\",\"https://ghost.org/pricing\"]],[\"a\",[\"href\",\"https://github.com/TryGhost\"]],[\"a\",[\"href\",\"/the-editor/\"]],[\"em\"]],\"sections\":[[1,\"p\",[[0,[],0,\""

Indeed it ends on an unterminated string literal about 265 characters in. So for some reason the generated mobiledoc is invalid/truncated.

As the problematic post is not one I am interested in, I would like to remove it. As I cannot remove it via Posts, could I just DELETE it from the database? Is there anything I have to consider?

Yes deleting from the db should not have any side effects when it comes to posts. But always make sure to have a backup before performing any actions like this :wink:

I’ll move ahead, carefully. Thanks a lot!