{"record":{"id":"1a9e827eeb8675b6","repo":"TryGhost/Ghost","slug":"ghost-container-not-initialized","errorCode":null,"errorMessage":"Ghost container not initialized","messagePattern":"Ghost container not initialized","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"e2e/helpers/environment/service-managers/ghost-manager.ts","lineNumber":226,"sourceCode":"\n    /**\n     * Bring up the egress-monitoring DNS sidecar for this worker (idempotent).\n     * Never throws — monitoring is best-effort and must not break the suite.\n     */\n    private async startEgressMonitor(): Promise<void> {\n        if (!EGRESS_MONITOR_ENABLED || this.egressMonitor) {\n            return;\n        }\n        const monitor = new EgressMonitor(this.docker, {\n            workerIndex: this.config.workerIndex\n        });\n        await monitor.start();\n        this.egressMonitor = monitor;\n    }\n\n    async restartWithDatabase(databaseName: string, extraConfig?: GhostEnvOverrides): Promise<void> {\n        if (!this.ghostContainer) {\n            throw new Error('Ghost container not initialized');\n        }\n\n        debug('Restarting Ghost with database:', databaseName);\n\n        const info = await this.ghostContainer.inspect();\n        const containerName = info.Name.replace(/^\\//, '');\n\n        // Remove old and create new with updated database\n        await this.removeContainer(this.ghostContainer);\n        this.ghostContainer = await this.createGhostContainer(containerName, databaseName, extraConfig);\n        await this.ghostContainer.start();\n\n        debug('Ghost restarted with database:', databaseName);\n    }\n\n    /**\n     * Wait for Ghost to become reachable through the same gateway path used by tests.\n     */","sourceCodeStart":208,"sourceCodeEnd":244,"githubUrl":"https://github.com/TryGhost/Ghost/blob/47d8b0e2ad2fd4757d3bc45f46c3ac165ff8a1fe/e2e/helpers/environment/service-managers/ghost-manager.ts#L208-L244","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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()."],"exampleFix":"// before\nawait ghostManager.restartWithDatabase('ghost_testing');\n\n// after\nif (!ghostManager.ghostContainer) {\n    throw new Error('restartWithDatabase called before Ghost container was created');\n}\nawait ghostManager.restartWithDatabase('ghost_testing');","handlingStrategy":"validation","validationCode":"function assertGhostReady(manager: GhostManager): void {\n    if (!manager.ghostContainer) {\n        throw new Error('restartWithDatabase called before Ghost container was created');\n    }\n}","typeGuard":"function ghostContainerReady(manager: GhostManager): manager is GhostManager & {ghostContainer: Container} {\n    return manager.ghostContainer != null;\n}","tryCatchPattern":null,"preventionTips":["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."],"tags":["e2e","lifecycle","fixture-ordering","state-management"],"backgroundTag":null,"analyzedSha":"47d8b0e2ad2fd4757d3bc45f46c3ac165ff8a1fe","analyzedAt":"2026-08-13T01:25:26.651Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}