TryGhost/Ghost · error · Error
Ghost container not initialized
Error message
Ghost container not initialized
What it means
restartWithDatabase() requires a live Ghost container but throws if this.ghostContainer is null/undefined. This container is created during setup (createGhostContainer + start) and stored on the manager. Reaching this throw means setup either never ran, failed before assignment, or a prior teardown nulled the reference. The method swaps the database by removing and recreating the container, so it cannot proceed without a baseline container.
Source
Thrown at e2e/helpers/environment/service-managers/ghost-manager.ts:226
/**
* Bring up the egress-monitoring DNS sidecar for this worker (idempotent).
* Never throws — monitoring is best-effort and must not break the suite.
*/
private async startEgressMonitor(): Promise<void> {
if (!EGRESS_MONITOR_ENABLED || this.egressMonitor) {
return;
}
const monitor = new EgressMonitor(this.docker, {
workerIndex: this.config.workerIndex
});
await monitor.start();
this.egressMonitor = monitor;
}
async restartWithDatabase(databaseName: string, extraConfig?: GhostEnvOverrides): Promise<void> {
if (!this.ghostContainer) {
throw new Error('Ghost container not initialized');
}
debug('Restarting Ghost with database:', databaseName);
const info = await this.ghostContainer.inspect();
const containerName = info.Name.replace(/^\//, '');
// Remove old and create new with updated database
await this.removeContainer(this.ghostContainer);
this.ghostContainer = await this.createGhostContainer(containerName, databaseName, extraConfig);
await this.ghostContainer.start();
debug('Ghost restarted with database:', databaseName);
}
/**
* Wait for Ghost to become reachable through the same gateway path used by tests.
*/View on GitHub (pinned to 47d8b0e2ad)
Solutions
- Ensure the Ghost instance fixture (ghostInstance) is resolved before any code path that calls restartWithDatabase().
- Verify setup completed: assert manager.ghostContainer is set before calling restart helpers, and surface the real setup failure if it isn't.
- If teardown nulls the container, re-create via createGhostContainer before calling restartWithDatabase().
Example fix
// before
await ghostManager.restartWithDatabase('ghost_testing');
// after
if (!ghostManager.ghostContainer) {
throw new Error('restartWithDatabase called before Ghost container was created');
}
await ghostManager.restartWithDatabase('ghost_testing'); Defensive patterns
Strategy: validation
Validate before calling
function assertGhostReady(manager: GhostManager): void {
if (!manager.ghostContainer) {
throw new Error('restartWithDatabase called before Ghost container was created');
}
} Type guard
function ghostContainerReady(manager: GhostManager): manager is GhostManager & {ghostContainer: Container} {
return manager.ghostContainer != null;
} Prevention
- Always go through the ghostInstance fixture so setup has run before any restart call.
- Never null the container reference in teardown without re-creating it.
- Add a precondition assertion in custom fixtures that orchestrate restarts.
When it happens
Trigger: Calling restartWithDatabase() before perTestSetup/instance initialization completed. A previous removeContainer() set this.ghostContainer = null but no new container was assigned. Test fixture ordering invoked a database-swap path before the Ghost fixture resolved.
Common situations: Custom test fixtures that orchestrate database swaps out of order; setup threw partway and left the manager in a half-initialized state; teardown ran in a beforeEach but setup didn't re-run.
Related errors
- [e2e fixture] Failed to initialize per-file Ghost instance.
- [e2e fixture] resetEnvironment() must be called before resol
- baseURL is not defined
- Cannot create without a persistence adapter. Use buildMany()
- Failed to create ${entityType}: ${response.status()} ${error
AI-assisted analysis of TryGhost/Ghost@47d8b0e2ad (2026-08-13).
Data as JSON: /api/errors/1a9e827eeb8675b6.
Report an issue: GitHub.