TryGhost/Ghost · error · Error

Timeout after ${timeoutMs}ms waiting for search results

Error message

Timeout after ${timeoutMs}ms waiting for search results

What it means

Thrown by `MailPit.searchWithWait` when the polling loop exits the timeout window without matching messages. The loop polls Mailpit's search endpoint every 500ms until it finds any message (or exactly `numberOfMessages`); exhaustion means the expected email never arrived in the window.

Source

Thrown at e2e/helpers/services/email/mail-pit.ts:136

        while (Date.now() - startTime < timeoutMs) {
            const messages = await searchFn();

            if (numberOfMessages === null) {
                if (messages.length > 0) {
                    debug(`Found ${messages.length} messages`);
                    return messages;
                }
            } else {
                if (messages.length === numberOfMessages) {
                    debug(`Found ${messages.length} messages`);
                    return messages;
                }
            }

            await this.delay(500);
        }

        throw new Error(`Timeout after ${timeoutMs}ms waiting for search results`);
    }

    private async delay(milliseconds: number) {
        await new Promise<void>((resolve) => {
            setTimeout(resolve, milliseconds);
        });
    }

    private async executeApiCall(endpoint: string, callType: string, method: string = 'GET'): Promise<Response> {
        debug(`${callType} through ${endpoint}`);
        const response = await fetch(`${this.apiUrl}/${endpoint}`, {method: method});
        if (!response.ok) {
            throw new Error(`Failed to ${callType}: ${response.statusText}`);
        }

        debug(`${callType} through ${endpoint} succeeded`);
        return response;
    }

View on GitHub (pinned to 47d8b0e2ad)

Solutions

  1. Increase `timeoutMs` for the search call in slow environments.
  2. Verify the search query parameters match how the email was actually sent (recipient address, subject).
  3. Confirm Ghost dispatched the email and Mailpit received it (check Mailpit UI/logs).
  4. Correct the expected `numberOfMessages` if the test assumption about email count is wrong.
Defensive patterns

Strategy: retry

Prevention

When it happens

Trigger: An email-dependent assertion waits for messages via `searchByRecipient`/`searchByQuery` with a timeout, and the condition (`messages.length > 0` or `=== numberOfMessages`) is never satisfied before `timeoutMs` elapses.

Common situations: Mailpit is slow to index; Ghost did not send the email; the recipient/search query does not match the sent mail; `numberOfMessages` expectation is wrong (too many/few); network latency between test runner and Mailpit.

Understand the failure class

Related errors


AI-assisted analysis of TryGhost/Ghost@47d8b0e2ad (2026-08-13). Data as JSON: /api/errors/58942fdd63b31404. Report an issue: GitHub.