TryGhost/Ghost · critical · Error
[e2e fixture] Failed to initialize per-file Ghost instance.
Error message
[e2e fixture] Failed to initialize per-file Ghost instance.
What it means
In per-file isolation, the fixture caches a Ghost instance (cachedPerFileInstance) and recycles it across files. If after the recycle logic activePerFileInstance is still falsy, setup never produced an instance — perFileSetup returned null/undefined or threw silently upstream and the cache stayed empty. The fixture cannot hand a null instance to tests.
Source
Thrown at e2e/helpers/playwright/fixture.ts:399
config: mergedConfig,
stripe
});
cachedPerFileInstance = {
suiteKey,
environmentSignature,
instance: nextPerFileInstance
};
cachedPerFileGhostAccountOwner = null;
cachedPerFileAuthenticatedSession = null;
if (previousPerFileInstance) {
await environmentManager.perTestTeardown(previousPerFileInstance);
}
}
const activePerFileInstance = cachedPerFileInstance;
if (!activePerFileInstance) {
throw new Error('[e2e fixture] Failed to initialize per-file Ghost instance.');
}
const holder = {...activePerFileInstance.instance};
const cycle = async () => {
const previousInstance = cachedPerFileInstance?.instance;
const nextInstance = await environmentManager.perTestSetup({
config: mergedConfig,
stripe
});
if (previousInstance) {
await environmentManager.perTestTeardown(previousInstance);
}
cachedPerFileInstance = {
suiteKey,
environmentSignature,
instance: nextInstanceView on GitHub (pinned to 47d8b0e2ad)
Solutions
- Inspect why perFileSetup returned falsy — add logging around environmentManager.perFileSetup to see its return value and any swallowed error.
- Ensure perFileSetup throws on real failure rather than returning null, so the root cause surfaces.
- Confirm isolation mode (per-file) is supported by the active environment manager.
- Check the stripe/config branch didn't skip instance creation for this file.
Example fix
// before
const activePerFileInstance = cachedPerFileInstance;
if (!activePerFileInstance) {
throw new Error('[e2e fixture] Failed to initialize per-file Ghost instance.');
}
// after
const activePerFileInstance = cachedPerFileInstance;
if (!activePerFileInstance) {
throw new Error(`[e2e fixture] per-file Ghost instance is null after setup (isolation=${resolvedIsolation}, stripe=${stripe}); see preceding perFileSetup logs`);
} Defensive patterns
Strategy: validation
Validate before calling
const inst = await environmentManager.perFileSetup({config: mergedConfig, stripe});
if (!inst?.instance) {
throw new Error('perFileSetup returned no instance — setup failed');
} Type guard
function isPerFileInstance(x: unknown): x is {instance: GhostInstance} {
return typeof x === 'object' && x !== null && 'instance' in x && x.instance != null;
} Try / catch
try {
cachedPerFileInstance = await environmentManager.perFileSetup({config: mergedConfig, stripe});
} catch (e) {
throw new Error('[e2e fixture] per-file setup threw', {cause: e});
}
if (!cachedPerFileInstance?.instance) {
throw new Error('[e2e fixture] per-file setup returned no instance');
} Prevention
- Make perFileSetup throw on failure instead of returning null so the root cause surfaces.
- Log perFileSetup return values during fixture bring-up to detect partial failures.
- Confirm the environment manager supports the resolved isolation mode.
When it happens
Trigger: environmentManager.perFileSetup returned a falsy instance (no error thrown). An earlier branch skipped instance creation. A previous perTestTeardown nulled the cache and the subsequent setup didn't repopulate. Misconfigured isolation mode resolved to per-file but the manager can't serve it.
Common situations: Environment manager implementation gap for per-file mode; setup partially failed and returned null instead of throwing; fixture conditionals (e.g. stripe flag) routed away from instance creation.
Related errors
- [e2e fixture] resetEnvironment() must be called before resol
- baseURL is not defined
- Ghost container not initialized
- 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/f94bf48f4f8e95a1.
Report an issue: GitHub.