I am getting the following error:
Error: Protocol error (Runtime.callFunctionOn): Cannot find context with specified id undefined
at Session._onMessage (/srv/node_modules/puppeteer-edge/lib/Connection.js:205:25)
at Connection._onMessage (/srv/node_modules/puppeteer-edge/lib/Connection.js:105:19)
at emitOne (events.js:115:13)
at WebSocket.emit (events.js:210:7)
at Receiver._receiver.onmessage (/srv/node_modules/ws/lib/WebSocket.js:143:47)
at Receiver.dataMessage (/srv/node_modules/ws/lib/Receiver.js:389:14)
at Receiver.getData (/srv/node_modules/ws/lib/Receiver.js:330:12)
at Receiver.startLoop (/srv/node_modules/ws/lib/Receiver.js:165:16)
at Receiver.add (/srv/node_modules/ws/lib/Receiver.js:139:10)
at Socket._ultron.on (/srv/node_modules/ws/lib/WebSocket.js:139:22)
at emitOne (events.js:115:13)
at Socket.emit (events.js:210:7)
at addChunk (_stream_readable.js:266:12)
at readableAddChunk (_stream_readable.js:253:11)
at Socket.Readable.push (_stream_readable.js:211:10)
at TCP.onread (net.js:585:20)
It is a large codebase and it is unclear whats triggering this error.
Any guides?
On that note, there needs to be a better way to throw error. Without knowing the origin of the error in the code it is impossible to trace down these exceptions.
I am in the same situation since I upgraded to v.0.13.0, this error appear before the page even start navigating…
Same for me! :angry:
@aslushnikov @JoelEinbinder can you help, please?
I am getting this error occasionally, and I have no idea where to catch this exception, so my browser hangs.
For now, I am disabling the load of websocket resources (because I don't need them) to see if that helps.
For now, I am disabling the load of websocket resources (because I don't need them) to see if that helps.
Did that help?
Did that help?
So far, my script didn't hang again. I am still monitoring but seems to be working for me. I will wait some extra hours of runtime to see how it goes.
You can set a request event listener and checking for the property request..resourceType == 'websocket'.
https://github.com/GoogleChrome/puppeteer/blob/master/docs/api.md#requestresourcetype
I disabled the websocket, but it doesn't work for me
was working on a [crawler](github.com/lrlna/puppeteer-crawler] with puppeteer and getting an error when trying to get a form to submit. seems the same, and is not websocket
related for me. does this give anyone a better idea on what could be happening?
walker.on('page', async (page) => {
var url = new URL(await page.url())
var pathname = url.href.replace(url.origin, '')
console.log('pathname:', pathname)
if (pathname === '/') {
try {
page.type('.signin [name=email]', '[email protected]')
page.type('.signin [name=password]', 'beepboop')
await page.$eval('.signin', form => form.submit())
} catch (err) {
console.log(err.stack)
}
}
})
Error: Protocol error (Runtime.callFunctionOn): Cannot find context with specified id undefined
at Session._onMessage (/Users/lrlna/developer/puppeteer-walker/node_modules/puppeteer/lib/Connection.js:205:25)
at Connection._onMessage (/Users/lrlna/developer/puppeteer-walker/node_modules/puppeteer/lib/Connection.js:105:19)
at emitOne (events.js:115:13)
at WebSocket.emit (events.js:210:7)
at Receiver._receiver.onmessage (/Users/lrlna/developer/puppeteer-walker/node_modules/ws/lib/WebSocket.js:143:47)
at Receiver.dataMessage (/Users/lrlna/developer/puppeteer-walker/node_modules/ws/lib/Receiver.js:389:14)
at Receiver.getData (/Users/lrlna/developer/puppeteer-walker/node_modules/ws/lib/Receiver.js:330:12)
at Receiver.startLoop (/Users/lrlna/developer/puppeteer-walker/node_modules/ws/lib/Receiver.js:165:16)
at Receiver.add (/Users/lrlna/developer/puppeteer-walker/node_modules/ws/lib/Receiver.js:139:10)
at Socket._ultron.on (/Users/lrlna/developer/puppeteer-walker/node_modules/ws/lib/WebSocket.js:139:22)
I had the same issue that was happening when I was doing a page.click('selector').
I reverted to puppeteer 0.12.0 and I had a much clearer error message (it was related to the element I wanted to click on that was not available yet). I fixed the issue by waiting for the element then updated again to 0.13.0 and it is now working fine.
Based on the info, the change probably happened in a Chromium roll between 0.12.0 and 0.13.0. There were a couple of updates in between those releases.
@aslushnikov @JoelEinbinder any weird changes to the protocol/chrome that would be related to this?
@gajus @acgpiano Just an update, my scripts hanged again (now in 0.13.0).
Hopefully the @aslushnikov commit will help, I will try to patch my current install with that code until the fix gets in a release.
This should be fixed on tip-of-tree now. Let me know if it's not.
Whats the reason it is not being released as 0.13.1?
Please start using https://github.com/semantic-release/semantic-release instead of making arbitrary release decisions.
@gajus as much as I'd like to see this issue fixed, but there is a good reason why it hasn't been released as 0.13.1 and it exactly relates to the semantic versioning. #1415 changes how frame.executionContext()
method works - it will return a promise.
BREAKING CHANGE: this patch changes frame.executionContext() method to return a promise.
To migrate onto a new behavior, await the context first before using it.
So I hope it will get into 0.14.x
Then why not release 0.14.0
? Like, now.
There is literally no reason whatsoever not to automate the releases. There is no reason whatsoever not to release a new version every time a PR has been merged into the master. If you merge something into the master, then it is ready for the release.
@aslushnikov I update to 1.0.0-rc and it still doesn't work.
```
Error: Protocol error (Runtime.callFunctionOn): Cannot find context with specified id undefined
at Session._onMessage (/Users/acgpiano/Security/crawler/node_modules/[email protected]@puppeteer/lib/Connection.js:205:25)
at Connection._onMessage (/Users/acgpiano/Security/crawler/node_modules/[email protected]@puppeteer/lib/Connection.js:105:19)
at emitOne (events.js:116:13)
at WebSocket.emit (events.js:211:7)
at Receiver._receiver.onmessage (/Users/acgpiano/Security/crawler/node_modules/[email protected]@ws/lib/WebSocket.js:143:47)
at Receiver.dataMessage (/Users/acgpiano/Security/crawler/node_modules/[email protected]@ws/lib/Receiver.js:389:14)
at Receiver.getData (/Users/acgpiano/Security/crawler/node_modules/[email protected]@ws/lib/Receiver.js:330:12)
at Receiver.startLoop (/Users/acgpiano/Security/crawler/node_modules/[email protected]@ws/lib/Receiver.js:165:16)
at Receiver.add (/Users/acgpiano/Security/crawler/node_modules/[email protected]@ws/lib/Receiver.js:139:10)
at Socket._ultron.on (/Users/acgpiano/Security/crawler/node_modules/[email protected]@ws/lib/WebSocket.js:139:22)
at emitOne (events.js:116:13)
at Socket.emit (events.js:211:7)
at addChunk (_stream_readable.js:263:12)
at readableAddChunk (_stream_readable.js:250:11)
at Socket.Readable.push (_stream_readable.js:208:10)
at TCP.onread (net.js:594:20)
@gajus the library is still prerelease. Automating deployment is probably best when things have stabilized all around. Things are still in a good bit of flux, so imo it is better updates be batched in case multiple breaking changes occur at once. Then developers just look over their existing code once instead on multiple times for multiple updates.
@gajus the library is still prerelease. Automating deployment is probably best when things have stabilized all around. Things are still in a good bit of flux, so imo it is better updates be batched in case multiple breaking changes occur at once. Then developers just look over their existing code once instead on multiple times for multiple updates.
This argument is nonsensical.
Making releases for every breaking change allows gradual adoption.
Batching updates complicates migration.
The developer makes a decision when to upgrade. No one is forcing you to update to the latest version the moment it becomes available.
Automation of release has nothing to do with maturity of the codebase. If code is not meant to be released, do not merge it into the master.
@gajus installing from master gives you the cadence you want....
I've installed from master but I'm still getting the same error thrown. Anyone else?
@gajus installing from master gives you the cadence you want....
Might as well not use package manager then, because you are telling users to pull code from the repository.
@gajus installing from master gives you the cadence you want....
Might as well not use package manager then, because you are telling users to pull code from the repository.
If you are open to start using semantic-release, I am happy to raise a PR that integrates semantic-release. Alternatively, you can have a look into any of the projects that I maintain, http://github.com/gajus.
Example:
From https://github.com/gajus/isomorphic-webpack
semantic-release
as a dev dependency.NPM_TOKEN
and GH_TOKEN
secrets variables to Travis configuration.It has been a month now since v0.13.0 release.
Instead of making regular releases as suggested in this thread, you have the entire user base locked in a broken version of Puppeteer.
I found a way to get around this issue that works for me. I made a little utility function as follows:
const waitFor = function(timeToWait) {
return new Promise(resolve => {
setTimeout(() => {
resolve(true);
}, timeToWait);
});
};
In my code I had the following calls next to each other. And the getProperty('href')
would throw the exception. But once I put the waitFor(3000)
in there things started working again.
const back = await page.$(elementSelectors.backButton);
back.click();
await page.waitFor(elementSelectors.backButton);
await utils.waitFor(3000); // This is where I had to add my custom waitFor()
const elms = await page.$$('a');
// ... some looping code
const href = await elms[i].getProperty('href'); // This would throw if I took out the custom waitFor()
@StephenGilboy Good call. Essentially, we need to wait on the browser to finish doing something and your function does just that. Wonder why the packages waitForNavigation
and other wait
methods are not working here.
using "puppeteer": "^0.13.0", I'm having a weird issue where uncommenting the following line, outside of evaluationContext, produces OP's error:
//sLineOfText = sLineOfText.replace(', ', '~');
repro here, and it's this file in particular.
Rolling back to "puppeteer": "0.12.0" solved the issue, but wanted to drop the info somewhere.
If you are open to start using semantic-release, I am happy to raise a PR that integrates semantic-release. Alternatively, you can have a look into any of the projects that I maintain, http://github.com/gajus.
@gajus Thank you for the suggestion. I'm not convinced your approach yields enough benefits, a few questions I have:
package.json
has version 1.4.6
, whereas the npm has 2.1.1
. Is this supposed to be like this?I also don't like that two unrelated topics are discussed in this thread. So can you please file a separate issue so that we move the semver releases discussion out from here.
@aslushnikov I update to 1.0.0-rc and it still doesn't work.
@acgpiano the previous patch fixed a race with execution context creation, however there's another one with execution context destruction. What I mean is:
Ideally, you'd like to run evaluation in the page that won't navigate away. Otherwise, throwing exception for this situation is the best we can do.
in the project you refer to, package.json has version 1.4.6, whereas the npm has 2.1.1. Is this supposed to be like this?
The version in the package.json is not relevant. The version information is pulled from NPM prior to making a release.
See this explanation, https://github.com/semantic-release/semantic-release#why-is-the-packagejsons-version-not-updated-in-my-repository.
how would this approach work with the documentation? It's currently hosted on github for all released versions
Whats the current process to publish the documentation?
It would be simply a matter of automating publishing of the documentation after semantic-release
script is done.
why installing from github doesn't work for early adopters?
For the same reason we have semantic versioning in the first place.
Someone who is consuming Puppeteer does not want to be using head
because that can introduce a breaking change. Equally, locking to a particular commit provides no way of checking if there is a more recent version.
When projects are setup to properly use semver, updating project dependencies is simply the matter of running a program such as https://www.npmjs.com/package/npm-check-updates. Imagine if every repository started to use your approach – maintaining project dependencies up to date would be a nightmare.
this error presented for me when changing passing timeout: 0
to page.launch
options. Changing it to a high value (300k, though not sure magnitude matters) solved the problem.
@ggobbe Thanks for your trouble shooting
I also had this error on 0.13.0
It errors on let text = await page.evaluate(() => document.body.textContent)
Protocol error (Runtime.callFunctionOn): Cannot find context with specified id undefined
at Session._onMessage (node_modules/puppeteer/lib/Connection.js:205:25)
Adding await page.waitFor(4000)
gives PASS.
Is there a 'better practice' way?
Thanks
I have the same error :
Error: Protocol error (Runtime.callFunctionOn): Cannot find context with specified id undefined
at Session._onMessage (W:\path\node_modules\puppeteer\lib\Connection.js:205:25)
at Connection._onMessage (W:\path\node_modules\puppeteer\lib\Connection.js:105:19)
at emitOne (events.js:116:13)
at WebSocket.emit (events.js:211:7)
at Receiver._receiver.onmessage (W:\path\node_modules\ws\lib\WebSocket.js:141:47)
at Receiver.dataMessage (W:\path\node_modules\ws\lib\Receiver.js:389:14)
at Receiver.getData (W:\path\node_modules\ws\lib\Receiver.js:330:12)
at Receiver.startLoop (W:\path\node_modules\ws\lib\Receiver.js:165:16)
at Receiver.add (W:\path\node_modules\ws\lib\Receiver.js:139:10)
at Socket._ultron.on (W:\path\node_modules\ws\lib\WebSocket.js:138:22)
Although, After some testing I figured that it was a (some elementHandle).click() call that was triggering it so after doing some search on possible fixes I came across #103 and tried changing the viewport:
from {width: 1280, height: 1024}
to {width: 1280, height: 720}
That actually solved my problem and the error didn't come up. See if it works for you...
I was consistently receiving the same error:
Error: Protocol error (Runtime.callFunctionOn): Cannot find context with specified id undefined
at Session._onMessage (/home/ubuntu/workspace/node_modules/puppeteer/lib/Connection.js:205:25)
at Connection._onMessage (/home/ubuntu/workspace/node_modules/puppeteer/lib/Connection.js:105:19)
at emitOne (events.js:115:13)
at WebSocket.emit (events.js:210:7)
at Receiver._receiver.onmessage (/home/ubuntu/workspace/node_modules/puppeteer/node_modules/ws/lib/WebSocket.js:141:47)
at Receiver.dataMessage (/home/ubuntu/workspace/node_modules/puppeteer/node_modules/ws/lib/Receiver.js:389:14)
at Receiver.getData (/home/ubuntu/workspace/node_modules/puppeteer/node_modules/ws/lib/Receiver.js:330:12)
at Receiver.startLoop (/home/ubuntu/workspace/node_modules/puppeteer/node_modules/ws/lib/Receiver.js:165:16)
at Receiver.add (/home/ubuntu/workspace/node_modules/puppeteer/node_modules/ws/lib/Receiver.js:139:10)
at Socket._ultron.on (/home/ubuntu/workspace/node_modules/puppeteer/node_modules/ws/lib/WebSocket.js:138:22)
I added await page.waitFor(4000);
in every place where I had await page.waitForNavigation({ waitUntil: 'networkidle0', timeout: 0 });
and I no longer am receiving the error. Now I am getting the following error, but the function does complete successfully after throwing this error. It's a step in the right direction!
Promise {
<rejected> Error: Page crashed!
at Page._onTargetCrashed (/home/ubuntu/workspace/node_modules/puppeteer/lib/Page.js:102:24)
at Session.Page.client.on.event (/home/ubuntu/workspace/node_modules/puppeteer/lib/Page.js:97:56)
at emitOne (events.js:115:13)
at Session.emit (events.js:210:7)
at Session._onMessage (/home/ubuntu/workspace/node_modules/puppeteer/lib/Connection.js:210:12)
at Connection._onMessage (/home/ubuntu/workspace/node_modules/puppeteer/lib/Connection.js:105:19)
at emitOne (events.js:115:13)
at WebSocket.emit (events.js:210:7)
at Receiver._receiver.onmessage (/home/ubuntu/workspace/node_modules/puppeteer/node_modules/ws/lib/WebSocket.js:141:47)
at Receiver.dataMessage (/home/ubuntu/workspace/node_modules/puppeteer/node_modules/ws/lib/Receiver.js:389:14) } reason: Error: Page crashed!
at Page._onTargetCrashed (/home/ubuntu/workspace/node_modules/puppeteer/lib/Page.js:102:24)
at Session.Page.client.on.event (/home/ubuntu/workspace/node_modules/puppeteer/lib/Page.js:97:56)
at emitOne (events.js:115:13)
at Session.emit (events.js:210:7)
at Session._onMessage (/home/ubuntu/workspace/node_modules/puppeteer/lib/Connection.js:210:12)
at Connection._onMessage (/home/ubuntu/workspace/node_modules/puppeteer/lib/Connection.js:105:19)
at emitOne (events.js:115:13)
at WebSocket.emit (events.js:210:7)
at Receiver._receiver.onmessage (/home/ubuntu/workspace/node_modules/puppeteer/node_modules/ws/lib/WebSocket.js:141:47)
at Receiver.dataMessage (/home/ubuntu/workspace/node_modules/puppeteer/node_modules/ws/lib/Receiver.js:389:14)
I tried changing the viewport, reverting back to the puppeteer version of 0.12.0, making sure all the timeouts were at 0, and a bunch of other things. Though nothing was working. But adding await page.waitFor(4000)
throughout the page did the trick, at least to get the function to work even if it's still throwing an error.
EDIT: I changed the await page.waitFor(4000)
to await page.waitFor(1000)
for a couple, but kept await page.waitFor(4000)
for the initial load of the web page and the more intensive calls and that worked.
EDIT: The above fix did not work on my other functions. Still getting that darn Page crashed error over and over even if I only put await page.waitFor(4000)
once. But if I changed it from 4000 or remove the page.waitFor it gives me the other errors.
This needs more attention. It hasn't even been acknowledged as a bug.
I have ceased using Puppeteer and ended up developing our own abstraction mostly because of this issue (and general project maintainer attitude towards this project).
Really a shame to see that what Google Chrome team are pushing as an "official" abstraction is being treated with such negligence.
As I am no longer using Puppeteer, I am closing this issue and unsubscribing. Project maintainers are welcome to re-open.
@aslushnikov Can this be reopened? The bug still exists and affects the rest of us.
Can this be reopened? The bug still exists and affects the rest of us.
@webnard Sure. Can you please answer a few questions so that we have something to work with:
npm i puppeteer@next
)Updated my repro mentioned 27 days ago to try tip-of-tree today.
So if you look at HEAD in my repro, SHA a31626, I tried tip-of-tree. I wish I could say "the issue is resolved" or "the issue persists" but instead I have to say "I see a different issue with tip-of-tree, not sure if the old one is resolved or not."
The issue I'm getting now says you cannot navigate to invalid URL undefined. Previously I think puppeteer just returned undefined in that case.
If you reset that branch (replace-puppeteer-bug-repro) to SHA 541d7e9 you can see the issue as previously reported (uncommenting //sLineOfText = sLineOfText.replace(', ', '~');
breaks but it shouldn't). As I stated at that time, rolling puppeteer back to v0.12 fixes the issue in my case.
@aslushnikov My primary concern is that I don't know where the issue is occurring. I'm wondering if anything could be done to improve the error message or call stack to indicate a more precise location of the fault.
@webnard The stack traces were improved with a164524c72443920e0f008d62c5362c08a7794a0 in response to this issue.
@aslushnikov
_Q: does the issue happens for you on tip-of-tree? (you can install latest puppeteer with npm i puppeteer@next)_
A: Yes, I just updated again to make sure and it's still giving me the same errors. If I fill in await page.waitFor(4000)
in place of every await page.waitForNavigation({ waitUntil: 'networkidle0', timeout: 0 })
then I get the initial "Cannot find context with specified id undefined" to stop appearing but depending on the function I've been getting the below errors. Everything finishes running despite the Page crashed warnings, so I'm not sure why they keep appearing. But before I updated everything worked by just adding await page.waitForNavigation({ waitUntil: 'networkidle', timeout: 0 })
(now networkidle0 or networkidle2).
Error: Page crashed!
at Page._onTargetCrashed (/home/ubuntu/workspace/node_modules/puppeteer/lib/Page.js:102:24)
at Session.Page.client.on.event (/home/ubuntu/workspace/node_modules/puppeteer/lib/Page.js:97:56)
at emitOne (events.js:116:13)
at Session.emit (events.js:211:7)
at Session._onMessage (/home/ubuntu/workspace/node_modules/puppeteer/lib/Connection.js:210:12)
at Connection._onMessage (/home/ubuntu/workspace/node_modules/puppeteer/lib/Connection.js:105:19)
at emitOne (events.js:116:13)
at WebSocket.emit (events.js:211:7)
at Receiver._receiver.onmessage (/home/ubuntu/workspace/node_modules/puppeteer/node_modules/ws/lib/WebSocket.js:141:47)
at Receiver.dataMessage (/home/ubuntu/workspace/node_modules/puppeteer/node_modules/ws/lib/Receiver.js:389:14)
at Receiver.getData (/home/ubuntu/workspace/node_modules/puppeteer/node_modules/ws/lib/Receiver.js:330:12)
at Receiver.startLoop (/home/ubuntu/workspace/node_modules/puppeteer/node_modules/ws/lib/Receiver.js:165:16)
at Receiver.add (/home/ubuntu/workspace/node_modules/puppeteer/node_modules/ws/lib/Receiver.js:139:10)
at Socket._ultron.on (/home/ubuntu/workspace/node_modules/puppeteer/node_modules/ws/lib/WebSocket.js:138:22)
at emitOne (events.js:116:13)
at Socket.emit (events.js:211:7)
Error Error: Protocol error (Runtime.callFunctionOn): Target closed.
at Session._onClosed (/home/ubuntu/workspace/node_modules/puppeteer/lib/Connection.js:221:23)
at Connection._onClose (/home/ubuntu/workspace/node_modules/puppeteer/lib/Connection.js:127:15)
at emitTwo (events.js:126:13)
at WebSocket.emit (events.js:214:7)
at WebSocket.emitClose (/home/ubuntu/workspace/node_modules/puppeteer/node_modules/ws/lib/WebSocket.js:211:10)
at _receiver.cleanup (/home/ubuntu/workspace/node_modules/puppeteer/node_modules/ws/lib/WebSocket.js:199:39)
at Receiver.cleanup (/home/ubuntu/workspace/node_modules/puppeteer/node_modules/ws/lib/Receiver.js:520:15)
at WebSocket.finalize (/home/ubuntu/workspace/node_modules/puppeteer/node_modules/ws/lib/WebSocket.js:199:20)
at emitNone (events.js:111:20)
at Socket.emit (events.js:208:7)
at endReadableNT (_stream_readable.js:1056:12)
at _combinedTickCallback (internal/process/next_tick.js:138:11)
at process._tickCallback (internal/process/next_tick.js:180:9)
_Q: are you sure the page is not navigating away as you run evaluations? In this case, the error is expected_
A: It appears it's no longer waiting for the full page to load like it was doing with await page.waitForNavigation({ waitUntil: 'networkidle', timeout: 0 })
before. I think it's not finding an element on the page, but the problem is that it's not waiting for the full page to load anymore.
_Q: do you have a repro?_
A: I only have private repos because it's got client information in there but I can copy/paste one of the functions.
@dallashuggins these page crashes are suspicious. They shouldn't happen in the first place, and when they do happen we don't handle them the right way (see #1454).
I'd appreciate if you can share some runnable code for me to reproduce the behavior.
Hey @aslushnikov - unfortunately the page I am trying to access requires you to login first, but I have shared the skeleton of the function below. Does this help?
After updating to 0.13.0 to 0.12.0, I had to change networkidle to networkidle2 or networkidle0, both of which give me the same results, and add the different await page.waitFor([#]);
throughout the script.
var credentials = {
un: '',
pw: ''
};
const checkProgress = async function(credentials) {
try {
const browser = await puppeteer.launch({headless: true, timeout: 0});
const page = await browser.newPage();
await page.waitFor(4000);
page.setViewport({ width: 2560, height: 1600 }); //{width: 1280, height: 720}
// Login:
await page.goto('[website]', { waitUntil: 'networkidle0', timeout: 0 });
await page.waitFor(4000);
await page.waitForNavigation({ waitUntil: 'networkidle0', timeout: 0 });
await page.waitFor(4000);
const username = await page.$('input#userInput');
await username.type(credentials.un);
const password = await page.$('input#passwordInput');
await password.type(credentials.pw);
const loginButton = await page.$('input#login-button[type=submit]');
await page.waitFor(1000);
await loginButton.click({ clickCount: 1, delay: 100 });
await page.waitFor(1000);
await page.waitForNavigation({ waitUntil: 'networkidle0', timeout: 0 });
// Navigate to the Reports page:
await page.goto('[website]', { waitUntil: 'networkidle0', timeout: 0 });
await page.waitFor(1000);
await page.waitForNavigation({ waitUntil: 'networkidle0', timeout: 0 });
await page.screenshot({ path: 'screenshot.png' });
// Evaluate HTML:
let bodyHTML = await page.evaluate(() => document.body.innerHTML);
var $ = cheerio.load(bodyHTML);
var tr = $('table.icwTable > tbody#myReportResults').children().first();
var td = tr.text();
var inProg = td.indexOf('In-Progress');
var ready = td.indexOf('Ready');
console.log("In Progress index:", inProg);
console.log("Ready index:", ready);
await page.waitFor(1000);
// Return In Progress or Ready
if (inProg > -1) {
console.log("In Progress", td);
await browser.close();
return "In Progress";
}
else if (ready > -1) {
console.log("Report is Ready:", td);
await browser.close();
return "Ready";
} else {
await browser.close();
return "Something went wrong";
}
} catch (err) {
console.log("Error", err);
throw new Error (err);
}
};
checkProgress(credentials);
This script works with the different page.waitFors throughout it; it gives the "Cannot find context with specified id undefined" otherwise. If the page.waitFors with the 1000 value are changed to 2000, it gives a Page crashed message; if you change those same ones to 3000 I then the Session closed error is returned.
Though I have other scripts which throw Page crashed or Session closed with too many page.waitFors on it, but Target closed, etc. if there's not enough - can't find that perfect middle. I can send those too if preferred.
@dallashuggins thank you for sharing the details. In this case, the Cannot find context with specified id undefined
error seems to be related to the page crashed
failure. The page crashed
error is a major problem; let's debug it first.
I've created a designated issue for this here: https://github.com/GoogleChrome/puppeteer/issues/1785
I noticed this fix: https://github.com/GoogleChrome/puppeteer/issues/396
which basically catches the error in the WaitTask
since the browser changed the context and ignore it. Not Don't know if it helps in any way, but it seems like the same error was fixed in another place.
In case you're still looking for a way to reproduce ([email protected]):
const puppeteer = require('puppeteer');
(async () => {
const browser = await puppeteer.launch();
try {
const page = await browser.newPage();
await page.goto('http://www.tomoni-praluent.jp');
const result = await page.evaluate(() => {
return [];
});
console.log(result);
} finally {
await browser.close();
}
})();
That code on that specific website pretty consistently produces a
Error: Protocol error (Runtime.callFunctionOn): Cannot find context with specified id undefined
at Promise (/project/node_modules/puppeteer/lib/Connection.js:185:56)
at new Promise (<anonymous>)
at CDPSession.send (/project/node_modules/puppeteer/lib/Connection.js:184:12)
at ExecutionContext.evaluateHandle (/project/node_modules/puppeteer/lib/ExecutionContext.js:62:75)
at ExecutionContext.evaluate (/project/node_modules/puppeteer/lib/ExecutionContext.js:41:31)
at Frame.evaluate (/project/node_modules/puppeteer/lib/FrameManager.js:290:20)
at <anonymous>
at process._tickCallback (internal/process/next_tick.js:160:7)
Either that or it returns undefined
from the .evaluate
call, which is also the wrong behavior.
It works as expected on other websites.
(Disclamer: I'm not affiliated with this website at all)
I got this same error and when I curl
ed the page, it was using a meta refresh client-side redirect. When I add a await page.waitFor
right after the goto
, it works perfectly
Thanks @JZL for the investigation.
@Janpot this matches the usecase described in this comment. To workaround, you should wait for certain page state using the page.waitFor
function.
I seem to be having the same problem and happens on certain pages when I try and click on them- most of the time it is irrelevant where I try and click, it results in the same error. This is using v1. I have the waituntillnetworkidle0
- what other generic event could I try and wait for?
@aslushnikov The behavior is kind of unpredictable. Most of the times it errors, but when it doesn't it returns undefined
for me. I'm ok with receiving an error, but when it doesn't error, I kind of expect a correct value.
Perhaps this is a debugging method.
Environment:
The test.js
script:
const puppeteer = require('puppeteer');
var page;
puppeteer.launch({
appMode: true,
args: ['--window-size=1920,1080']
})
.then(async browser => {
page = (await browser.pages())[0];
page.setDefaultNavigationTimeout(60000);
page.once('load', () => {
console.log('load finished.')
});
await page.goto('https://stackoverflow.com/');
// click Tags
await ((await page.$x('//a[@id="nav-tags"]'))[0].click());
// await page.waitForNavigation({
// timeout:10000,
// waitUntil:'networkidle0'
// });
// get the url after the jump
console.log(await page.evaluate(() => document.URL));
})
Run node test.js
and the log is:
load finished.
(node:9660) UnhandledPromiseRejectionWarning: Error: Protocol error (Runtime.callFunctionOn): Cannot find context with specified id undefined
at Promise (/home/x3e6/tool/node-v9.3.0-linux-x64/lib/node_modules/puppeteer/lib/Connection.js:185:56)
at new Promise (<anonymous>)
at CDPSession.send (/home/x3e6/tool/node-v9.3.0-linux-x64/lib/node_modules/puppeteer/lib/Connection.js:184:12)
at ExecutionContext.evaluateHandle (/home/x3e6/tool/node-v9.3.0-linux-x64/lib/node_modules/puppeteer/lib/ExecutionContext.js:62:75)
at ExecutionContext.evaluate (/home/x3e6/tool/node-v9.3.0-linux-x64/lib/node_modules/puppeteer/lib/ExecutionContext.js:41:31)
at Frame.evaluate (/home/x3e6/tool/node-v9.3.0-linux-x64/lib/node_modules/puppeteer/lib/FrameManager.js:290:20)
at <anonymous>
at process._tickCallback (internal/process/next_tick.js:160:7)
(node:9660) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:9660) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
Add DEBUG environment variables for debugging:
DEBUG=puppeteer:*
Rerun node test.js
, The partial log is:
puppeteer:protocol ◀ RECV {"method":"Target.receivedMessageFromTarget","params":{"sessionId":"153736FB1906DF5B5054B897B2416B58:1","message":"{\"error\":{\"code\":-32000,\"message\":\"Cannot find context with specified id\"},\"id\":18}","targetId":"153736FB1906DF5B5054B897B2416B58"}} +0ms
puppeteer:session ◀ RECV {"error":{"code":-32000,"message":"Cannot find context with specified id"},"id":18} +0ms
(node:11284) UnhandledPromiseRejectionWarning: Error: Protocol error (Runtime.callFunctionOn): Cannot find context with specified id undefined
at Promise (/home/x3e6/tool/node-v9.3.0-linux-x64/lib/node_modules/puppeteer/lib/Connection.js:185:56)
at new Promise (<anonymous>)
at CDPSession.send (/home/x3e6/tool/node-v9.3.0-linux-x64/lib/node_modules/puppeteer/lib/Connection.js:184:12)
at CDPSession.<anonymous> (/home/x3e6/tool/node-v9.3.0-linux-x64/lib/node_modules/puppeteer/lib/helper.js:121:23)
at ExecutionContext.evaluateHandle (/home/x3e6/tool/node-v9.3.0-linux-x64/lib/node_modules/puppeteer/lib/ExecutionContext.js:62:75)
at ExecutionContext.evaluate (/home/x3e6/tool/node-v9.3.0-linux-x64/lib/node_modules/puppeteer/lib/ExecutionContext.js:41:31)
at Frame.evaluate (/home/x3e6/tool/node-v9.3.0-linux-x64/lib/node_modules/puppeteer/lib/FrameManager.js:290:20)
at <anonymous>
at process._tickCallback (internal/process/next_tick.js:160:7)
Pay attention to this sentence:
"message":"{\"error\":{\"code\":-32000,\"message\":\"Cannot find context with specified id\"},\"id\":18}"
Search "id":18
in all log (WebStorm output), just in front, not far from the error message, there is a:
puppeteer:session SEND ► {"id":18,"method":"Runtime.callFunctionOn","params":{"functionDeclaration":"() => document.URL","executionContextId":1,"arguments":[],"returnByValue":false,"awaitPromise":true}} +0ms
The Runtime.callFunctionOn
also appeared in the error output, and the "functionDeclaration":"() => document.URL"
is where the error occurred.
After reading all the comments on this issue, according to the error message "Can not find context with
specified id undefined " and some people mentioned calling page.waitForXXX
, it looks like when page.evaluate started running, the page was not loaded yet after the click was run, so due to lack of context, the error occurred.
Uncomment await page.waitForNavigation ...
in my test.js
and rerun node test.js
, it works perfectly and the output is:
load finished.
https://stackoverflow.com/tags
After clicking, the page jumps but does not trigger the load
event ... (???)
I'm getting this error too. Example code (looping through an array of urls, to re-use a page, was to try and repro another issue I was having... instead I ran into this one):
const loadPage = function (i, page, url) {
return new Promise(async (resolve, reject) => {
page.on('pageerror', errorstring => {
reject(new Error(errorstring));
});
page.on('error', error => {
reject(new Error(error));
});
try {
await page.setViewport({ width: 400, height: 200 });
const watchDog = page.waitForFunction('window.allDoneNow == true', { polling: 250, timeout: 5000 });
const ignoreThisPromiseAndAwaitWatchdogInstead = page.goto(url);
await watchDog;
await page.screenshot({ path: 'screenshot_' + i + '.png' });
resolve();
} catch (error) {
reject(new Error(error));
}
});
};
(async () => {
var browser, page;
try {
const url = 'https://cloud3squared.com/files/example.html';
const urls = [url, url];
browser = await puppeteer.launch();
page = await browser.newPage();
for (var i = 0; i < urls.length; i++) {
await loadPage(i, page, urls[i]);
}
} catch (error) {
console.log('error:', error);
} finally {
await page.close();
await browser.close();
}
})();
The html page is:
<html>
<head>
<title>
A Very Basic HTML Document
</title>
<script type="text/javascript">
document.addEventListener('DOMContentLoaded', function(event) {
delete window.allDoneNow;
setTimeout(function() {
document.getElementById("my_text").innerHTML = "Great! You waited for the best bit!";
window.allDoneNow = true;
}, 2500);
});
</script>
</head>
<body>
<div id="my_text">This is boring... wait for the good bit!</div>
</body>
</html>
The screenshots are taken OK, but I get the following error:
(node:49715) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): Error: Protocol error (Runtime.callFunctionOn): Cannot find context with specified id undefined
I've tried as best I can to catch any rejected promises... clearly haven't managed.
Hey folks, are we sure that runtime.clearExecutionContexts
is doing the right thing?
In the code it clears out all execution contexts in all frames. The reason I ask is that I'm also running into this in a different library. It doesn't happen all the time, only occassionally.
Here's a full feed of the actions (most of these logs correspond to puppeteer actions):
=== RUN TestClick
DevTools listening on ws://127.0.0.1:53553/devtools/browser/224356af-06f2-4a9d-ba05-af67173d5d12
INFO[0023] set main frame id=9612C9BCADCD1D4AAA6C9241958BDAD4 parent=<nil>
INFO[0023] chrome/page/goto: navigating url=https://google.com
INFO[0024] chrome/frame/waituntil: still waiting for events events=unload id=9612C9BCADCD1D4AAA6C9241958BDAD4
INFO[0024] chrome/frame/setlifecycle: setting lifecycle event=init id=9612C9BCADCD1D4AAA6C9241958BDAD4
INFO[0024] chrome/frame/setlifecycle: set navigating channel
INFO[0024] chrome/frame/clearexecutioncontext: cleared all execution contexts frame=9612C9BCADCD1D4AAA6C9241958BDAD4
INFO[0024] chome/page: execution context destroyed: couldn't find the frame id execution=1
INFO[0024] chrome/frame/addexecutioncontext: added an execution context frame=9612C9BCADCD1D4AAA6C9241958BDAD4 id=2 is_default=true
INFO[0024] chrome/frame/setlifecycle: setting lifecycle event=firstPaint id=9612C9BCADCD1D4AAA6C9241958BDAD4
INFO[0024] chrome/frame/setlifecycle: setting lifecycle event=firstContentfulPaint id=9612C9BCADCD1D4AAA6C9241958BDAD4
INFO[0024] chrome/frame/setlifecycle: setting lifecycle event=firstTextPaint id=9612C9BCADCD1D4AAA6C9241958BDAD4
INFO[0024] chrome/frame/setlifecycle: setting lifecycle event=firstImagePaint id=9612C9BCADCD1D4AAA6C9241958BDAD4
INFO[0024] chrome/frame/setlifecycle: setting lifecycle event=firstMeaningfulPaintCandidate id=9612C9BCADCD1D4AAA6C9241958BDAD4
INFO[0024] chrome/frame/setlifecycle: setting lifecycle event=firstMeaningfulPaintCandidate id=9612C9BCADCD1D4AAA6C9241958BDAD4
INFO[0024] chrome/frame/setlifecycle: setting lifecycle event=DOMContentLoaded id=9612C9BCADCD1D4AAA6C9241958BDAD4
INFO[0024] chrome/frame/waituntil: event found event=unload id=9612C9BCADCD1D4AAA6C9241958BDAD4
INFO[0024] chrome/frame/waituntil: event found event=DOMContentLoaded id=9612C9BCADCD1D4AAA6C9241958BDAD4
INFO[0024] chrome/frame/waituntil: still waiting for events events=load id=9612C9BCADCD1D4AAA6C9241958BDAD4
INFO[0024] chrome/frame/setlifecycle: setting lifecycle event=load id=9612C9BCADCD1D4AAA6C9241958BDAD4
INFO[0025] chrome/frame/waituntil: event found event=load id=9612C9BCADCD1D4AAA6C9241958BDAD4
INFO[0025] chrome/frame/waituntil: still waiting for events events=unload, DOMContentLoaded, load id=9612C9BCADCD1D4AAA6C9241958BDAD4
INFO[0025] chrome/frame/setlifecycle: setting lifecycle event=init id=9612C9BCADCD1D4AAA6C9241958BDAD4
INFO[0025] chrome/frame/setlifecycle: set navigating channel
INFO[0025] chrome/frame/setlifecycle: setting lifecycle event=firstMeaningfulPaint id=9612C9BCADCD1D4AAA6C9241958BDAD4
INFO[0025] chrome/frame/setlifecycle: setting lifecycle event=networkAlmostIdle id=9612C9BCADCD1D4AAA6C9241958BDAD4
INFO[0025] chrome/frame/setlifecycle: setting lifecycle event=networkIdle id=9612C9BCADCD1D4AAA6C9241958BDAD4
INFO[0025] chrome/frame/waituntil: event found event=unload id=9612C9BCADCD1D4AAA6C9241958BDAD4
INFO[0025] chrome/frame/waituntil: still waiting for events events=DOMContentLoaded, load id=9612C9BCADCD1D4AAA6C9241958BDAD4
INFO[0025] chrome/frame/setlifecycle: setting lifecycle event=init id=9612C9BCADCD1D4AAA6C9241958BDAD4
INFO[0025] chrome/frame/setlifecycle: set navigating channel
INFO[0026] chrome/frame/removeexecutioncontext: removing execution context id=2
INFO[0026] chrome/frame/addexecutioncontext: added an execution context frame=9612C9BCADCD1D4AAA6C9241958BDAD4 id=3 is_default=true
INFO[0026] chrome/frame/clearexecutioncontext: cleared all execution contexts frame=9612C9BCADCD1D4AAA6C9241958BDAD4
INFO[0026] chrome/frame/setlifecycle: setting lifecycle event=firstPaint id=9612C9BCADCD1D4AAA6C9241958BDAD4
INFO[0026] chrome/frame/setlifecycle: setting lifecycle event=firstMeaningfulPaintCandidate id=9612C9BCADCD1D4AAA6C9241958BDAD4
INFO[0026] chrome/frame/setlifecycle: setting lifecycle event=firstContentfulPaint id=9612C9BCADCD1D4AAA6C9241958BDAD4
INFO[0026] chrome/frame/setlifecycle: setting lifecycle event=firstTextPaint id=9612C9BCADCD1D4AAA6C9241958BDAD4
INFO[0026] chrome/frame/setlifecycle: setting lifecycle event=DOMContentLoaded id=9612C9BCADCD1D4AAA6C9241958BDAD4
INFO[0026] chrome/frame/setlifecycle: setting lifecycle event=firstImagePaint id=9612C9BCADCD1D4AAA6C9241958BDAD4
INFO[0026] chrome/frame/setlifecycle: setting lifecycle event=load id=9612C9BCADCD1D4AAA6C9241958BDAD4
INFO[0026] chrome/frame/setlifecycle: setting lifecycle event=firstMeaningfulPaintCandidate id=9612C9BCADCD1D4AAA6C9241958BDAD4
INFO[0026] chrome/frame/setlifecycle: setting lifecycle event=firstMeaningfulPaintCandidate id=9612C9BCADCD1D4AAA6C9241958BDAD4
INFO[0027] chrome/frame/waituntil: event found event=DOMContentLoaded id=9612C9BCADCD1D4AAA6C9241958BDAD4
INFO[0027] chrome/frame/waituntil: event found event=load id=9612C9BCADCD1D4AAA6C9241958BDAD4
INFO[0027] chrome/frame/setlifecycle: setting lifecycle event=firstMeaningfulPaint id=9612C9BCADCD1D4AAA6C9241958BDAD4
INFO[0027] chrome/frame/setlifecycle: setting lifecycle event=networkAlmostIdle id=9612C9BCADCD1D4AAA6C9241958BDAD4
INFO[0027] chrome/frame/setlifecycle: setting lifecycle event=networkIdle id=9612C9BCADCD1D4AAA6C9241958BDAD4
INFO[0027] chrome/page/title: getting title of main frame
INFO[0027] chrome/frame/defaultexecutioncontext: getting the default execution context id=9612C9BCADCD1D4AAA6C9241958BDAD4
--- FAIL: TestClick (8.56s)
chrome_test.go:106: chrome/page: unable to get the default execution context: headless/retrier: timed out: chrome/frame: couldn't find the default execution context
From the looks of it, it seems like the most important bit is here:
INFO[0026] chrome/frame/removeexecutioncontext: removing execution context id=2
INFO[0026] chrome/frame/addexecutioncontext: added an execution context frame=9612C9BCADCD1D4AAA6C9241958BDAD4 id=3 is_default=true
INFO[0026] chrome/frame/clearexecutioncontext: cleared all execution contexts frame=9612C9BCADCD1D4AAA6C9241958BDAD4
Oh! You know I bet it's a race condition between adding new execution contexts and clearing out previous execution contexts 😀
The order should probably be:
INFO[0026] chrome/frame/removeexecutioncontext: removing execution context id=2
INFO[0026] chrome/frame/clearexecutioncontext: cleared all execution contexts frame=9612C9BCADCD1D4AAA6C9241958BDAD4
INFO[0026] chrome/frame/addexecutioncontext: added an execution context frame=9612C9BCADCD1D4AAA6C9241958BDAD4 id=3 is_default=true
Follow up, do we even need to clear the executions? Or can we just let runtime.executionContextDestroyed
do it's thing?
FYI I seem to have worked around this temporarily with this:
_wait-for-navigation-and-context.js_
/*
This resolves an issue where puppeteer cannot interact with the page yet because
a context is not defined. This is usually related to navigation.
See also: https://github.com/GoogleChrome/puppeteer/issues/1325
*/
const promiseRetry = require('promise-retry')
const timeout = 1000
const iv = 100
module.exports = (page, maxTimeout = 120000) => promiseRetry(async (retry, number) => {
try {
await page.evaluate(iv => {
return new Promise((resolve, reject) => {
checkReadyState()
function checkReadyState() {
if (document.readyState === 'complete') {
resolve()
}
else {
setTimeout(checkReadyState, iv)
}
}
})
}, iv)
} catch (err) {
if (err.message.indexOf('Cannot find context with specified id undefined') !== -1) {
retry()
} else {
throw err
}
}
}, { retries: Math.ceil(maxTimeout / timeout), minTimeout: timeout, maxTimeout: timeout })
Usage:
await page.goto(parsedUrl.href, navigationOpts)
await waitForNavigationAndContext(page, 60000)
await waitForNavigationAndContext(page)
It is working !!! Thank you tommedema !!!
@NickSniper good to hear. I did rewrite it slightly not to use the iv
variable outside the evaluate
scope. See my edited post.
@tommedema
Thanks for your code, but in my case, it did not help :(
It's so sad that the issue exists soooo long.
In my case, I've a list of items on the page and I need to click on each of them to visit a connected page (similar to search result).
Every time when I click and/or wait I face similar message
Cannot find context with specified id undefined
Is there any solution yet?
@nnnikolay I guess the best way to solve it would be to have a standalone and small reproducible test case, including the html of a simplified version of the site you're operating on.
At the risk of spamming, I'm going to post this again, so we can stay on top of the actual issue:
The underlying problem is that there is a race condition between the event that clears execution contexts and the event that adds new execution contexts.
When you navigate to a new page, sometimes headless chrome will add the new contexts, before clearing the old ones. When it goes to clear the contexts, it blows away the recently added context, causing: Cannot find context with specified id undefined
.
I think the fix should come from upstream, since I think it's going to be quite difficult to handle correctly in puppeteer.
I suspect #2021 is related to that same race condition.
As crazy as this might sound, I've found a quick workaround for this "_Error: Protocol error (Runtime.evaluate): Cannot find context with specified id undefined'_" issue.
I was trying to evaluate whatever contents within a page "on load" event handler, but I kept getting this error for one specific website (never happened with hundred of others).
I simply added an await page.waitFor("//html")
line, and it fixed it...
initPageOnLoad() {
this._page.on("load", async () => {
if(this._onLoadInjectJS) {
console.log(" [On.pageLoad] Injecting JS dependencies on page loading...");
await this.injectFile(paths.utils);
}
});
}
async injectFile(filePath, page=null) {
let currentPage = page===null ? this._page : page;
let contents = await new Promise((resolve, reject) => {
fs.readFile(filePath, 'utf8', (err, data) => {
if (err) return reject(err);
resolve(data);
});
});
contents += `//# sourceURL=` + filePath.replace(/\n/g,'');
// If we remove this line, we would have the undefined context error
await currentPage.waitFor("//html");
return currentPage.mainFrame().evaluate(contents);
}
The version of my puppeteer is 1.0.0 . And I met the same question:
So it is uergent for me that I want to the easy anwser what is.
Another awesome example:
const puppeteer = require('puppeteer');
(async() => {
const browser = await puppeteer.launch({
headless: false,
timeout: 10000
});
const page = await browser.newPage();
await page.setViewport({
width: 1280,
height: 800
});
await page.goto('http://example.com/');
try {
await page.evaluate(() => {
window.test = false;
});
await page.mouse.click(340, 298); // click without expecting navigation
await page.evaluate(() => {
window.test = true;
});
} catch (e) {
console.log(e);
}
})();
@schelkun indeed, I think it's essentially the same issue as #2021. Looks like #2073 will fix it.
@Janpot I'm getting this error with the latest puppeteer version from this repo.
Me too, version 1.1.1 seems to still have this issue for me.
In my code I had this:
page.on('response', async () => {
doStuffHere()
...
Adding await page.waitForSelector('html')
seemed to fix the issue:
page.on('response', async () => {
await page.waitForSelector('html')
doStuffHere()
...
As I understand, the issue is related to the fact, that sometimes the page is not loaded when calling page.evaluate(). I've been investigating the error and noticed when it occurs certain conditions are met.
For example:
const puppeteer = require('puppeteer');
(async function() {
const browser = await puppeteer.launch({headless: true});
const page = await browser.newPage();
await page.goto('about:blank'); // or any other url
console.log(page.url()); // (1)
await page.goto('https://github.com'); // or any other url
console.log(page.url()); // (2)
await page.evaluate(function() {
// empty body
});
await browser.close();
})();
In the code above in line (2) page.url() should output 'https://github.com' and page.evaluate() should execute without error. But in some circumstances (for instance looping through hundreds of pages, many tabs open) I get the error 'Cannot find context with specified id ...' . And when that error occurs page.url() in line (2) always outputs 'about:blank' (or any other url I use). So, that clearly suggests that the page has not been fully loaded and the url has not changed. That also suggests there maybe something wrong with the page.goto() method.
If you're looking for an easy way to reproduce this, try this:
const puppeteer = require('puppeteer');
(async () => {
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.setRequestInterception(true);
page.on('request', request => {
const resourceType = request.resourceType();
const requestUrl = request.url();
request.continue();
});
page.on('response', response => {
// console.log(response.status(), response.url());
});
await page.setJavaScriptEnabled(false);
await page.goto('https://www.facebook.com');
const htmlVanilla = await page.content();
// await page.screenshot({ path: 'facebook.png' });
await page.setJavaScriptEnabled(true);
const response = await page.goto('https://www.facebook.com', {
waitUntil: 'networkidle0'
});
const htmlJS = await page.content();
await page.screenshot({ path: 'facebook2.png' });
await browser.close();
})();
▶ cat package.json | grep '"puppeteer"'
"puppeteer": "^1.0.0"
▶ node --trace-warnings hack.facebook.js
(node:4588) UnhandledPromiseRejectionWarning: Error: Protocol error (Runtime.callFunctionOn): Cannot find context with specified id undefined
at Promise (/Users/peterbe/dev/JAVASCRIPT/minimalcss/node_modules/puppeteer/lib/Connection.js:185:56)
at new Promise (<anonymous>)
at CDPSession.send (/Users/peterbe/dev/JAVASCRIPT/minimalcss/node_modules/puppeteer/lib/Connection.js:184:12)
at ExecutionContext.evaluateHandle (/Users/peterbe/dev/JAVASCRIPT/minimalcss/node_modules/puppeteer/lib/ExecutionContext.js:62:75)
at ExecutionContext.evaluate (/Users/peterbe/dev/JAVASCRIPT/minimalcss/node_modules/puppeteer/lib/ExecutionContext.js:41:31)
at Frame.evaluate (/Users/peterbe/dev/JAVASCRIPT/minimalcss/node_modules/puppeteer/lib/FrameManager.js:290:20)
at <anonymous>
at process._tickCallback (internal/process/next_tick.js:160:7)
at emitWarning (internal/process/promises.js:65:17)
at emitPendingUnhandledRejections (internal/process/promises.js:109:11)
at process._tickCallback (internal/process/next_tick.js:161:7)
(node:4588) Error: Protocol error (Runtime.callFunctionOn): Cannot find context with specified id undefined
at Promise (/Users/peterbe/dev/JAVASCRIPT/minimalcss/node_modules/puppeteer/lib/Connection.js:185:56)
at new Promise (<anonymous>)
at CDPSession.send (/Users/peterbe/dev/JAVASCRIPT/minimalcss/node_modules/puppeteer/lib/Connection.js:184:12)
at ExecutionContext.evaluateHandle (/Users/peterbe/dev/JAVASCRIPT/minimalcss/node_modules/puppeteer/lib/ExecutionContext.js:62:75)
at ExecutionContext.evaluate (/Users/peterbe/dev/JAVASCRIPT/minimalcss/node_modules/puppeteer/lib/ExecutionContext.js:41:31)
at Frame.evaluate (/Users/peterbe/dev/JAVASCRIPT/minimalcss/node_modules/puppeteer/lib/FrameManager.js:290:20)
at <anonymous>
at process._tickCallback (internal/process/next_tick.js:160:7)
(node:4588) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
at emitWarning (internal/process/promises.js:92:15)
at emitPendingUnhandledRejections (internal/process/promises.js:109:11)
at process._tickCallback (internal/process/next_tick.js:161:7)
^C
Fails every time.
I get the same error, every 30mins in a page ( whether I refresh or not, it's still going to happen ).
Is there any way to handle this gracefully somehow?
Right now it will get thrown in all the pages I have, and it will effectively make me restart every single page.
_tried puppeteer 1.1.1 and 1.2.0_
This issue is causing some minor havoc still. I'm running a bunch of instances every 5 minutes, executing the same script. The error occurs at random intervals which on scripts that work perfectly the next time. Very curious on how to solve this.
Running Puppeteer 1.2.0.
@aslushnikov I would be happy to add some specific debugging statements or logging. I could generate a ton of logging in a day or so to help triage this issue.
I'm facing this same issue. I believe it happens after calling a goto
and then requesting a screenshot
closely afterwards (while the page is still navigating).
I don't use the screenshot thing at all.
In my case, it comes when the page I loaded, auto reloads itself ( the page code for some reason auto-reloads every 30 mins roughly )
So at that point I lose all connection to the page I think, and that error comes from within the library.
I reverted to using CRI, where I can handle that reload just fine.
I really hope puppeteer fixes this, because it's API is a bit more convenient.
@sean-hill @AntouanK the case for me is even simpler:
runs fine roughly 29 out of 30 times and then fails once.
Also ran across this while doing page.evaluate
. Downgrading to 1.1.0 solved the problem for me.
@aslushnikov I would be happy to add some specific debugging statements or logging. I could generate a ton of logging in a day or so to help triage this issue.
@tnolet the logs generated by "DEBUG=puppeteer:session" will help a lot to debug this.
Able to reproduce this anytime when the page decides to navigate itself. Would a simple test case help the team here?
Able to reproduce this anytime when the page decides to navigate itself. Would a simple test case help the team here?
@KevinGrandon This looks similar to the situation described in the second part of this comment. What would you expect the command to return instead of exception?
Also, note: there's a FR for the navigation lock that should help here.
I've been seeing this issue as well. Any news on said issue?
@aslushnikov I will add debugging ASAP and report back
Happens to me when the goto
ed page does a redirect.
e.g.
await page.goto("https://example.com/page", {"waitUntil": "networkidle2"});
// if the above page redirects to https://www.example.com/page/ the next line will throw the exception
await page.evaluate(()=> someWindowPropThatExists);
Case I had: first I created an array from page.$$eval(). I needed to click on each element. Just the first click worked. It turned out the page was reloaded each time clicked and the array was no longer available within the new page. I resolved it by regenerating page.$$eval after each click.
I'm getting this error when trying to type a username and a password, it was working fine yesterday:
(node:21648) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): Error: Protocol error (Runtime.evaluate): Cannot find context with specified id undefined
await page.type('#uname', USERNAME);
await page.type('#pword', PASSWORD);
I solved this by adding await page.waitForNavigation({waitUntil: 'load'}); before typing in
A couple of updates ocurred which I think made the error start, one being changing puppeteer from 1.2.0 to 1.3.0
Still seeing the same issue as well, use case:
await page.goto(url, {waitUntil: 'networkidle2'});
and then page.$eval(someElement, callback
. I believe it's the same issues as everyone mentioned above when page.$eval
or any sort of page interaction began without the page being fully loaded. Not sure if switching to waitUntil: 'networkidle0' will resolve the issue since this happens sporadically for me so far.
I can confirm from our side that the issue appears related to calls to page.waitForSelector()
(and possibly other page-content-related functions) that appear directly after page.goto()
calls.
We have worked around this by introducing a 1 second delay between page.goto()
and page.waitForSelector()
and this appears to be avoiding the issue.
Our stack trace (puppeteer 1.3.0):
Error: Protocol error (Runtime.callFunctionOn): Cannot find context with specified id undefined
at Promise (/home/teamcity/BuildAgent/work/da93de6565e40d48/node_modules/puppeteer/lib/Connection.js:200:56)
at new Promise (<anonymous>)
at CDPSession.send (/home/teamcity/BuildAgent/work/da93de6565e40d48/node_modules/puppeteer/lib/Connection.js:199:12)
at ExecutionContext.evaluateHandle (/home/teamcity/BuildAgent/work/da93de6565e40d48/node_modules/puppeteer/lib/ExecutionContext.js:73:75)
at ExecutionContext.evaluate (/home/teamcity/BuildAgent/work/da93de6565e40d48/node_modules/puppeteer/lib/ExecutionContext.js:46:31)
at Frame.evaluate (/home/teamcity/BuildAgent/work/da93de6565e40d48/node_modules/puppeteer/lib/FrameManager.js:326:20)
at <anonymous>
I was digging into this the other day because it was causing issues for us pretty consistently for a site. What triggered it for us was a race condition between page navigation and trying to find an element. What it boiled down to was that a navigation event happened between these two lines. The document
object was retrieved from one context, the navigation happened, and then the document
object was used to try to find an element but it fails with the error discussed here because the context of the document
was destroyed by the navigation.
Adding an explicit wait time before all of this obviously helps, but that's fairly non-deterministic. Is there an easy way to check if a context has been destroyed without having to actually make a call via devtools protocol? For now, when encountering this error, we just retry what we were trying to do.
This error is occurring to me in [email protected]/1.2/1.3. The logs are the same. I removed all waitForNavigation()
methods and added explicit timeout before each waitForSelector()
, but it still throws an error(very inconsistently though). I'm using node pool to reuse the instance of the browser, so it should not be related to excessive memory usage.
The problem existing in both headless and real browser.
However in real browser, i'm using page.click before page.type, then the problem is resolved.
Above solution does not work in headless mode
❗️ I'm getting the same error. I can't share the entire codebase or provide a full repro since it's closed source and has lots of moving parts, but here is the code that I'm pretty sure is causing the issue:
console.log('Clicking Submit');
try {
console.log('before 123');
await page.evaluateHandle(passwordInput => passwordInput.form.submit(), passwordInput);
console.log('after 123')
} catch (err) {
console.log('Caught error!!!!', err)
}
The output I get when I run it is:
Clicking Submit
before 123
after 123
Running AutoLogin: 389.826ms
(node:22339) UnhandledPromiseRejectionWarning: Error: Protocol error (Runtime.callFunctionOn): Cannot find context with specified id undefined
at Promise (/Users/davidnagli/Desktop/coding/projects/Axex/server/node_modules/puppeteer/lib/Connection.js:200:56)
at new Promise (<anonymous>)
at CDPSession.send (/Users/davidnagli/Desktop/coding/projects/Axex/server/node_modules/puppeteer/lib/Connection.js:199:12)
at ExecutionContext.evaluateHandle (/Users/davidnagli/Desktop/coding/projects/Axex/server/node_modules/puppeteer/lib/ExecutionContext.js:73:75)
at ExecutionContext.evaluate (/Users/davidnagli/Desktop/coding/projects/Axex/server/node_modules/puppeteer/lib/ExecutionContext.js:46:31)
at Frame.evaluate (/Users/davidnagli/Desktop/coding/projects/Axex/server/node_modules/puppeteer/lib/FrameManager.js:326:20)
at <anonymous>
at process._tickDomainCallback (internal/process/next_tick.js:228:7)
(node:22339) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:22339) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
Notice that the error occurs after after 123
is already logged, and the error never get's caught by the try-catch
. 😟
Another important thing to note is that in my page.evaluateHandle
call I'm submitting a form. My theory is that maybe since I'm navigating to another page before the evaluation completes that's causing the issue 🤷♂️
I noticed that this issue has been getting a ton of comments and very little replies from contributors, so it would be amazing if one you guys can just quickly explain what's the status of this bug and let us know if you need any more info you need to help reproduce it. If I would understand the issue better I'd be happy to submit a PR.
A heads up for anyone hitting this issue - check through your code to make sure there is not a missing await
on an earlier call. This can lead to a race condition and cause the error on a later, seemingly unrelated line.
I hit this issue and reading through the comments, I can see a few people that have a similar possible error in their code, so hopefully that helps someone.
I've done:
page.on('request', (request) => {
urlChanged++;
});
page.on('requestfailed', () => {
if (urlChanged > 0) {
urlChanged--;
}
});
page.on('requestfinished', () => {
if (urlChanged > 0) {
urlChanged--;
}
});
...
async function waitForPageReady(waitUntil = ['networkidle2'], timeOut = 5000)
{
const timeOutPromise = new Promise(async function (resolve) {
await setTimeout(() => {
urlChanged = 0;
resolve('timedOut');
}, timeOut);
});
const urlChangedPromise = new Promise(async function (resolve) {
while (urlChanged > 0) {
await new Promise((innerResolve) => {
setTimeout(innerResolve, 1000)
});
}
resolve('UrlChanged decreased');
});
const result = await Promise.race([timeOutPromise, urlChangedPromise]);
}
and just dotted await waitForPageReady();
around my code when I think the URL may change.
I had the problem where form buttons were being pressed and one of them triggered a page load (submit) but even though the mouse control was on an await, the script continued running and then I tried to screenshot the page but the page hadn't loaded at that point. Using the above code worked around it.
My experience with this error is that it's happening when the URL has a redirect.
This occurred to my when I forgot to await page.goto(url).
Further to @zaius - I was not await
ing a call to page.setViewport
Hi, encountered this problem when updating code that was using puppeteer < 1.0 to newest version. I was also able to find source of the problem.
First, my reproduction script
const puppeteer = require('puppeteer');
let page;
const sleep = (time) => new Promise(resolve => setTimeout(resolve, time));
function wait() {
page
.waitForSelector('body')
.then(() => {
wait();
})
.catch(e => {});
}
(async () => {
const browser = await puppeteer.launch();
page = await browser.newPage();
wait();
for(let i = 0; i < 10; i += 1) {
await sleep(1000);
await page.goto('http://example.com/');
}
await browser.close();
})().catch(e => {});
with error:
(node:47660) UnhandledPromiseRejectionWarning: Error: Protocol error (Runtime.callFunctionOn): Cannot find context with specified id undefined
at Promise (/Users/jakubbogucki/Projects/GeneratorChisel/puppeteer-test/node_modules/puppeteer/lib/Connection.js:200:56)
at new Promise (<anonymous>)
at CDPSession.send (/Users/jakubbogucki/Projects/GeneratorChisel/puppeteer-test/node_modules/puppeteer/lib/Connection.js:199:12)
at ExecutionContext.evaluateHandle (/Users/jakubbogucki/Projects/GeneratorChisel/puppeteer-test/node_modules/puppeteer/lib/ExecutionContext.js:79:75)
at ExecutionContext.evaluate (/Users/jakubbogucki/Projects/GeneratorChisel/puppeteer-test/node_modules/puppeteer/lib/ExecutionContext.js:46:31)
at Frame.evaluate (/Users/jakubbogucki/Projects/GeneratorChisel/puppeteer-test/node_modules/puppeteer/lib/FrameManager.js:326:20)
at <anonymous>
at process._tickCallback (internal/process/next_tick.js:188:7)
Please note that it doesn't happen every time so I added the loop, but possibly 10 runs may be not enough.
End the source of the problem is that line:
https://github.com/GoogleChrome/puppeteer/blob/808bf8e5582482a1d849ff22a51e52024810905c/lib/FrameManager.js#L875
You can replace evaluation with
this._frame.evaluate(s => !s, success).catch(e => {})
If you look at rerun
function as a whole you will see that earlier it is wrapping evaluation in try/catch and handles errors but that evaluation is not protected in any way. Ironically later there is check for Cannot find context with specified id
but it is never reached if second evaluation fails.
/cc @JoelEinbinder @aslushnikov author and reviewer of #1746 that introduced the problematic line
@jakub300 ran the test script and it does exactly match the behaviour I notice "in production". Hope this helps fixing the issue.
I just want to get the html of the page. so I make my code like this
var resp = await page.goto(url, {timeout:120000}); var html = await resp.text();
😱OMG this is epic would mean the world to users of https://checklyhq.com as it was sometimes screwing with the dependability of using Puppeteer scripts for testing and monitoring.
🎉
What solved it for me was changing:
await page.waitForNavigation({waitUntil: 'networkidle0'});
to
await page.waitForNavigation();
... in one instance at least
Also, running into this intermittently now. Any plans for this to get fixed?
@elie222 Have you checked if you have any unresolved promises? It seems to me that this issue is caused by attempting to reuse a closed connection.
@aslushnikov , I am getting Error: Protocol error (Runtime.callFunctionOn): Cannot find context with specified id. when I am selecting in dropdown, but it can able to select still throws error.
ssample code is below
page.waitForSelector('#selector');
page.select('#selector', value);
Just adding another voice on this one: if you hit this while trying to do a form submission or something using evaluate()
that causes navigation to occur, try not returning anything from evaluate()
.
This throws the error:
let waitForSubmit = page.waitForNavigation();
await page.evaluate(() => $("#contentwrapper > form").submit());
await waitForSubmit;
This works correctly:
let waitForSubmit = page.waitForNavigation();
await page.evaluate(() => {
$("#contentwrapper > form").submit();
});
await waitForSubmit;
@dxinteractive yes, if the page.evaluate
causes a navigation, than the execution context where the evaluation is happenning will self-destruct, and page.evaluate
call will throw an error.
I you anticipate that your evaluation might trigger a navigation, than I'd recommend to gracefully
handle this exception in your script.
Most helpful comment
Hi, encountered this problem when updating code that was using puppeteer < 1.0 to newest version. I was also able to find source of the problem.
First, my reproduction script
with error:
Please note that it doesn't happen every time so I added the loop, but possibly 10 runs may be not enough.
End the source of the problem is that line:
https://github.com/GoogleChrome/puppeteer/blob/808bf8e5582482a1d849ff22a51e52024810905c/lib/FrameManager.js#L875
You can replace evaluation with
If you look at
rerun
function as a whole you will see that earlier it is wrapping evaluation in try/catch and handles errors but that evaluation is not protected in any way. Ironically later there is check forCannot find context with specified id
but it is never reached if second evaluation fails./cc @JoelEinbinder @aslushnikov author and reviewer of #1746 that introduced the problematic line