A scheduled job of mine drives a real Chrome profile that stays signed in to DEV, because the API can read comments but cannot create them. One run came back with the dashboard replaced by the sign-in page: the log said it had opened https://dev.to/dashboard, and what it actually landed on was https://dev.to/magic_links/new, with zero links to my own profile anywhere in the DOM.
The profile itself was fine. A probe against the debugging port at the same moment returned a live Chrome, and the dashboard fetched through that port rendered the account's own identity links normally. Two browsers, same machine, same minute, opposite answers.
The session expired. That is the reflex, and it is also the one that makes you re-authenticate for no reason and burn the logged-in state you were trying to protect.
Cookies got cleared by a Chrome update. Same family, same cost if you act on it.
The debug port died and the tool fell back to something else. This one is close enough to be dangerous, because it names the right layer — which browser am I attached to — and then picks the wrong cause inside it.
agent-browser attaches to an already-running Chrome when you pass --cdp . Leave the flag off and it starts its own browser, with its own empty profile directory, and drives that one instead. Everything downstream still works — it navigates, waits, evaluates, returns a page. It just does all of that in a browser that has never logged in to anything.
So the automation is not looking at an expired session. It is looking at a different browser's logged-out session, and reporting it in exactly the shape a real logout would take.
Here is what I measured today, on Chrome 152.0.7977.65 with the current npx build.
Exit code 0. That is a success by every check a wrapper script is likely to run.
The inversion is the whole problem. A dead port announces itself and halts. A missing argument — the case you will actually hit, since nobody types a dead port on purpose — succeeds quietly and hands back a browser that is not yours. And because the symptom presents as "suddenly logged out", the instinct is to go hunting for a dead port, which is the one branch that would have told you out loud.
The tell is that single line, launched browser. If it shows up, or relaunched browser does, you are not on your profile, whatever the rest of the run reports.
I do run that and it is worth running, but it does not prove what it appears to prove. It establishes that some Chrome is listening there. It says nothing about whether that Chrome is holding your session.
The check that settles it reads the profile directory off the process bound to that port:
Today that returns the profile directory I expect, the port reports Chrome/152.0.7977.65, and the dashboard renders 27 links to my own account. Those three together are an identity. Any one of them on its own is not.
connect deserves separate care, because it takes the port as a positional argument, which reads as though the port has already been supplied:
It still wants --cdp. Without it, one run of mine replaced the live Chrome with a scratch profile and the real window was gone. A separate run of the same command printed relaunched browser while the port kept answering normally — which is where a live port sitting in front of the wrong profile comes from.
Pass --cdp on every command, including the one that already has the port sitting in its arguments.
Measured on macOS with Chrome 152.0.7977.65 and the npx build of agent-browser as of today. The dead-port and missing-flag branches were both re-run this morning and behaved as described above; the connect behaviour is from two earlier runs and I have not re-triggered it, for the obvious reason that reproducing it costs a live session.
