apify/crawlee · error · Error
Cannot add session with id
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.
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…
- Default route is already defined! / Route for label
- <dynamic: blocked-request message returned by…
- <dynamic: message extracted from proxied error via…
- (possible values: 'Cloudflare challenge failed, found…
AI-assisted analysis of apify/crawlee@dbe57fb09c (2026-08-30).
Data as JSON: /api/errors/51580dabfe177266.
Report an issue: GitHub.
Appendix: 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)