apify/crawlee · error · Error

Cannot add session with id '${id}' as it already exists in t

Error message

Cannot add session with id '${id}' as it already exists in the pool

What it means

SessionPool.addSession() throws when a session with the same explicit id already exists in the pool's internal map. Duplicate session ids would break pooling state tracking, so the pool rejects them eagerly.

Source

Thrown at packages/core/src/session_pool/session_pool.ts:273

        await this.maybeLoadSessionPool();

        this.#listener = this.persistState.bind(this);
        this.#events.on(EventType.PERSIST_STATE, this.#listener);
    }

    /**
     * Adds a new session to the session pool. The pool automatically creates sessions up to the maximum size of the pool,
     * but this allows you to add more sessions once the max pool size is reached.
     * This also allows you to add session with overridden session options (e.g. with specific session id).
     * @param [options] The configuration options for the session being added to the session pool.
     */
    async addSession(options: Session | SessionOptions = {}): Promise<void> {
        await this.ensureInitialized();
        const { id } = options;
        if (id) {
            const sessionExists = this.#sessionMap.has(id);
            if (sessionExists) {
                throw new Error(`Cannot add session with id '${id}' as it already exists in the pool`);
            }
        }

        if (!this.hasSpaceForSession()) {
            this.removeRetiredSessions();
        }

        const newSession = options instanceof Session ? options : await this.invokeCreateSessionFunction(options);
        this.#log.debug(`Adding new Session - ${newSession.id}`);

        this.registerSession(newSession);
    }

    /**
     * Adds a new session to the session pool. The pool automatically creates sessions up to the maximum size of the pool,
     * but this allows you to add more sessions once the max pool size is reached.
     * This also allows you to add session with overridden session options (e.g. with specific session id).
     * @param [options] The configuration options for the session being added to the session pool.

View on GitHub (pinned to dbe57fb09c)

Solutions

  1. Check pool session existence (e.g. via getSession(id) / internal state) before calling addSession with an explicit id.
  2. Omit the id and let the pool generate unique ids.
  3. Remove the existing/retired session before re-adding one with the same id.
  4. Guard re-add logic in recovery code so it runs only when the pool is empty.

Example fix

// before
await pool.addSession({ id: 'user-1' });
await pool.addSession({ id: 'user-1' }); // throws

// after
if (!await pool.getSession('user-1') && !pool.retiredSessionsCount) {
    await pool.addSession({ id: 'user-1' });
}
Defensive patterns

Strategy: validation

Validate before calling

const existing = await pool.getSession(id).catch(() => null);
if (!existing) {
    await pool.addSession({ id });
}

Try / catch

try {
    await pool.addSession({ id });
} catch (e) {
    if (e instanceof Error && e.message.includes('already exists in the pool')) {
        // session already present – safe to skip
    } else throw e;
}

Prevention

When it happens

Trigger: Calling pool.addSession({ id: 'same-id' }) twice without removing the first session; or calling addSession for an id that crawlee itself already created inside the pool.

Common situations: Pre-seeding sessions from a saved state file and also re-adding them in code, retry logic that re-adds sessions on pool reinitialization, or concurrent addSession calls with the same id.

Related errors


AI-assisted analysis of apify/crawlee@dbe57fb09c (2026-08-30). Data as JSON: /api/errors/51580dabfe177266. Report an issue: GitHub.