Are you sure this is a bug? Yes — startup crash loop due to unhandled promise rejection.
Issue Summary
After upgrading to Ghost 6.10.3, the instance can enter a crash/restart loop during boot. The failure path is an unhandled promise rejection in the background services initialization, causing the process to exit repeatedly without a clear, actionable error in standard logs.
Explain roughly what’s wrong
A startup path in Ghost core (boot sequence) rejects a promise (background services init) without a catch, leading to an unhandled rejection and process termination.
What did you expect to happen?
- Startup should handle rejections, emit a clear error with context, and either recover or fail gracefully without an unhandled rejection.
Steps to Reproduce
-
Self-host Ghost using Ghost-CLI and systemd.
-
Upgrade to Ghost 6.10.3.
-
Start the service (e.g., systemctl start ghost_).
-
Observe the service enter a restart loop; logs show a rejection during startup with limited context.
Setup information
-
Ghost Version: 6.10.3
-
Node.js Version: v22.21.1
-
How did you install Ghost? Ghost-CLI (systemd-managed service)
-
Host & OS: Linux with systemd (self-hosted)
-
Database type: MySQL 8 (adjust if different)
-
Browser & OS version: N/A (server-side startup crash)
Relevant log / error output
Example symptoms:
Unhandled promise rejection during startup (background services init)
Process exits and systemd restarts service (loop)
Note: Adding a .catch() around the background services initialization (in core/boot.js) stops the crash loop and surfaces a proper error, suggesting the root cause is an unhandled rejection in that path.
Are you sure this is a bug? Yes — CLI throws an error object with an undefined message due to IPC handling logic.
Issue Summary
When Ghost sends an IPC message without an error object (or with error: undefined), Ghost-CLI still invokes instance.process.error({message: message.error}), which produces { message: undefined } and throws. This obscures the underlying Ghost error and contributes to confusing crash-loop diagnostics.
Explain roughly what’s wrong
Ghost-CLI doesn’t validate message.error in its run command IPC handler, and treats an undefined/null error as a regular error object.
What did you expect to happen?
-
Ghost-CLI should check for undefined/null before calling the error handler.
-
If the IPC payload lacks a meaningful error, CLI should log a clear warning and not throw a synthetic { message: undefined }.
Steps to Reproduce
-
Self-host Ghost using Ghost-CLI and systemd.
-
Upgrade to Ghost 6.10.3.
-
Start via Ghost-CLI/systemd.
-
Observe CLI surfacing errors like { message: undefined } during startup failure scenarios (from Ghost’s IPC notify path).
Setup information
-
Ghost Version: 6.10.3
-
Node.js Version: v22.21.1
-
How did you install Ghost? Ghost-CLI (systemd-managed service)
-
Host & OS: Linux with systemd (self-hosted)
-
Database type: MySQL 8 (adjust if different)
-
Browser & OS version: N/A (CLI-side error handling)
Relevant log / error output
Representative symptom:
=== Ghost CLI Process Manager Error ===
Error type: Object
Error message: undefined
Error string: [object Object]
…
Code path context (Ghost-CLI run command):
-
The IPC handler calls the process manager’s error method with {message: message.error} even when message.error is undefined.
-
Adding a guard (only call error if message.error != null) prevents { message: undefined } from being thrown and improves diagnostics.
Hey @pmichelu , welcome to Ghost!
I’m going to put your two reports together, because it seems likely they’re related, and that way we’ve got all the context in one place.
Just to confirm: You said you’re upgrading, right? From what version?
Hi @Cathy_Sarisky - thanks!
From version 3.0.3 if you can believe it. It was painful (syncing up the MySQL version with the intermediate updates was critical because MySQL 8.0 did not seem compatible with many of the v4 and v5 updates.
Thanks for combining the posts.