Protocol error (Target.activateTarget): Session closed
Learn how to fix the 'Session closed' error when trying to interact with a closed browser session
Ivan Muñoz
Apr 30, 2025
Crash

This error occurs when you try to interact with a browser session that has been closed or disconnected. This typically happens due to premature session closure or connection issues.
Common Causes
- Premature session closure: Browser session is closed before operations complete
- Connection issues: Network problems causing session disconnection
- Resource cleanup: Automatic cleanup closing sessions too early
- Multiple session handling: Trying to use a closed session
- Error handling issues: Session closes during error recovery
Solutions
1. Implement proper session management
let browser;
let page;
async function initializeSession() {
browser = await puppeteer.launch({
// Add connection options
args: ['--no-sandbox'],
timeout: 30000
});
page = await browser.newPage();
return { browser, page };
}
async function cleanupSession() {
if (page) await page.close();
if (browser) await browser.close();
}
// Usage
try {
const { browser, page } = await initializeSession();
await page.goto('https://example.com');
// ... your automation code ...
} catch (error) {
console.error('Error:', error);
} finally {
await cleanupSession();
}
2. Add session state checks
async function safeOperation(page, operation) {
if (!page || !page.isConnected()) {
throw new Error('Page session is closed or invalid');
}
try {
await operation();
} catch (error) {
if (error.message.includes('Session closed')) {
console.log('Session was closed during operation');
// Handle the error appropriately
}
throw error;
}
}
3. Implement session recovery
async function runWithSessionRecovery() {
let browser = await puppeteer.launch();
let page = await browser.newPage();
try {
await page.goto('https://example.com');
// ... your automation code ...
} catch (error) {
if (error.message.includes('Session closed')) {
console.log('Session was closed, attempting recovery...');
// Clean up old session
await browser.close();
// Create new session
browser = await puppeteer.launch();
page = await browser.newPage();
await page.goto('https://example.com');
}
throw error;
}
}
4. Use session event listeners
const browser = await puppeteer.launch();
// Listen for browser disconnect
browser.on('disconnected', () => {
console.log('Browser session was disconnected');
});
// Listen for target changes
browser.on('targetcreated', async (target) => {
console.log('New target created:', target.url());
});
browser.on('targetdestroyed', async (target) => {
console.log('Target destroyed:', target.url());
});
5. Implement retry logic with session checks
async function operateWithRetry(page, operation, maxRetries = 3) {
for (let i = 0; i < maxRetries; i++) {
try {
if (!page.isConnected()) {
throw new Error('Session is closed');
}
await operation();
return;
} catch (error) {
if (i === maxRetries - 1) throw error;
console.log(`Retry ${i + 1} of ${maxRetries}`);
// Wait before retrying
await new Promise(resolve => setTimeout(resolve, 1000));
}
}
}
Still Encountering Issues?
If you’re still having trouble with session closure errors, you can use a visual testing tool like Buglesstack to debug your automation and track session lifecycle events.
try {
await page.goto('https://www.google.com/search?q=puppeteer');
await page.waitForSelector('[name="q"]');
}
catch (error) {
// Prepare buglesstack data
const buglesstackData = {
url: page.url(),
screenshot: await page.screenshot({ encoding: 'base64' }),
html: await page.content(),
metadata: {},
message: error.message,
stack: error.stack
};
// Get your access token from https://app.buglesstack.com
const ACCESS_TOKEN = 'HERE_YOUR_ACCESS_TOKEN';
// Send error to buglesstack
await axios.post('https://app.buglesstack.com/api/v1/crashes', buglesstackData, {
headers: {
Authorization: `Bearer ${ACCESS_TOKEN}`,
'Content-Type': 'application/json'
}
});
// Re-throw the error to propagate it
throw error;
}
By implementing proper session management and error handling, you can resolve the “Session closed” error and make your automation more robust.