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
- Check pool session existence (e.g. via getSession(id) / internal state) before calling addSession with an explicit id.
- Omit the id and let the pool generate unique ids.
- Remove the existing/retired session before re-adding one with the same id.
- 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
- Look up the session before adding one with an explicit id.
- Let the pool auto-generate ids unless you must control them.
- Make session-seeding idempotent (check-then-add or catch-and-skip).
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
- The current SessionPool instance couldn't find a valid sessi
- Request blocked - received ${statusCode} status code.
- ${error} (possible values: 'Cloudflare challenge failed, fou
- ${this.getMessageFromError(error)}
- Default route is already defined! / Route for label '${Strin
AI-assisted analysis of apify/crawlee@dbe57fb09c (2026-08-30).
Data as JSON: /api/errors/51580dabfe177266.
Report an issue: GitHub.