TryGhost/Ghost · error · Error
baseURL is not defined
Error message
baseURL is not defined
What it means
The ghostAccountOwner fixture asserts ghostInstance.baseUrl is truthy before creating the test owner. A falsy baseUrl means the Ghost instance fixture didn't produce a URL — setup didn't run, failed, or the instance is in a state where no gateway URL was assigned. This guard fails fast rather than passing undefined into User creation/API calls.
Source
Thrown at e2e/helpers/playwright/fixture.ts:543
if (!stripeEnabled || !baseURL || !stripeServer) {
await use(undefined);
return;
}
const webhookClient = new WebhookClient(baseURL);
const service = new StripeTestService(stripeServer, webhookClient);
await use(service);
},
baseURL: async ({ghostInstance, _testEnvironmentContext}, use) => {
_testEnvironmentContext.markResetEnvironmentBlocker('baseURL');
await use(ghostInstance.baseUrl);
},
// Create user credentials only (no authentication)
ghostAccountOwner: async ({ghostInstance, _testEnvironmentContext}, use) => {
if (!ghostInstance.baseUrl) {
throw new Error('baseURL is not defined');
}
_testEnvironmentContext.markResetEnvironmentBlocker('ghostAccountOwner');
if (_testEnvironmentContext.resolvedIsolation === 'per-file' && cachedPerFileGhostAccountOwner) {
await use(cachedPerFileGhostAccountOwner);
return;
}
// Create user in this Ghost instance
const ghostAccountOwner: User = {
name: 'Test User',
email: `test${faker.string.uuid()}@ghost.org`,
password: 'test@123@test'
};
await setupUser(ghostInstance.baseUrl, ghostAccountOwner);
if (_testEnvironmentContext.resolvedIsolation === 'per-file') {View on GitHub (pinned to 47d8b0e2ad)
Solutions
- Ensure the ghostInstance fixture fully completes (container + gateway ready) before ghostAccountOwner is used — check waitForReady ran.
- Log ghostInstance in the fixture to see what baseUrl (and the rest) actually resolved to.
- Make instance setup throw (rather than return a baseUrl-less object) so the real failure surfaces earlier.
- Confirm the gateway port assignment path (getGatewayPort) ran during setup.
Example fix
// before
if (!ghostInstance.baseUrl) {
throw new Error('baseURL is not defined');
}
// after
if (!ghostInstance.baseUrl) {
throw new Error(`baseURL is not defined (instance state: ${JSON.stringify({running: !!ghostInstance.container, port: ghostInstance.port})})`);
} Defensive patterns
Strategy: validation
Validate before calling
if (!ghostInstance.baseUrl) {
throw new Error(`ghostInstance.baseUrl missing (setup incomplete: ${JSON.stringify({container: !!ghostInstance.container})})`);
} Type guard
function instanceHasBaseUrl(i: GhostInstance): i is GhostInstance & {baseUrl: string} {
return typeof i.baseUrl === 'string' && i.baseUrl.length > 0;
} Prevention
- Ensure ghostInstance setup fully completes (gateway port assigned) before dependent fixtures run.
- Make instance setup throw rather than return a baseUrl-less object.
- Log ghostInstance state in the fixture when baseUrl is missing to find the upstream cause.
When it happens
Trigger: ghostInstance fixture resolved but baseUrl is empty (instance not started, gateway port not assigned). Fixture ordering pulled ghostAccountOwner without ghostInstance completing properly. Instance creation returned an object lacking baseUrl.
Common situations: Setup failed silently and returned a partial instance; gateway never came up so baseUrl wasn't set; fixture misconfiguration where ghostAccountOwner is requested without the ghost instance being ready.
Related errors
- [e2e fixture] Failed to initialize per-file Ghost instance.
- [e2e fixture] resetEnvironment() must be called before resol
- 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/6a98f07a4133a2ed.
Report an issue: GitHub.