Why starting a browser no longer puts the profile in the cloud
Cloud sync roams a profile between machines: the identity, the cookies, the storage, the passkeys. It is genuinely useful for the handful of profiles you open from a laptop and a desktop. It is not useful for task-317, and a launch has no way of telling those apart. So it stopped guessing.
The failure this removes
If starting a browser also creates the cloud profile, then a script deciding to name its profiles after task IDs is a script deciding to fill your sync quota. Nobody writes that line of code on purpose. It arrives as a side effect of a loop, and you find it later by wondering why the number in the dashboard is what it is.
The uncomfortable part is that undoing it is manual. Creation was one implicit call per iteration; cleanup is you, in a list.
Three states, not two
sync is a tri-state, and the third state is the default:
sync: truecreates the cloud profile if it does not exist and syncs it.sync: falsestays local, always, regardless of what the server knows.- Unset syncs only if the server already knows that profile name. If it does not, the launch is local-only and nothing is created.
await ab.launch({ profile: 'main-account', sync: true }) // create and sync
await ab.launch({ profile: 'main-account' }) // syncs, it exists now
await ab.launch({ profile: 'scratch-01' }) // local, nothing created
The default is the interesting one. It means an existing synced profile keeps syncing without you passing anything, which is what you want for the profiles you actually roam, while a name the server has never heard of never becomes a cloud profile by accident. Automation gets the safe behaviour without opting into it, and the profiles you set up by hand keep the behaviour you set up.
sync: true on a plan without cloud sync throws rather than proceeding quietly. You asked for a specific thing; getting a local profile and no error would mean discovering the gap when you sit down at the second machine.
One notice, not silence
Defaulting to local has its own failure mode: you meant to sync, you did not pass anything, and you find out much later. So the first launch of an unknown name on a sync-capable plan prints a single line saying the profile is local-only and how to change that. Once per name per process, so a loop over 400 tasks does not turn into 400 lines of log noise.
You can route it wherever your logs go. The point is that the quiet path tells you it was quiet.
It cannot be combined with temporary profiles
Asking for sync: true and temporary: true together throws. Temporary profiles live in a tree that never talks to the server at all, described in where automation profiles should live, so there is no coherent reading of both at once. Choosing one silently would leave you with a profile you believed was syncing that was not, which is the exact class of bug the throw exists to prevent.
What syncing actually moves
Enough to make the profile the same profile on the other machine: the generated identity, the cookie and storage databases, and the passkey store. That last one matters more than it sounds, because a passkey has no password fallback. If the only copy is on a machine you no longer have, the account is not recoverable by resetting anything, a point covered in profile backup and migration.
Sync is per profile and opt-in per profile. It is not a mode you turn on for the account.
When local-only is the right answer
If you use one machine, cloud sync is solving a problem you do not have. Local profiles are unlimited on every plan including the free one, and a portable export gives you a copy you hold, on your own disk, with no service in the path. For a lot of people that is a better answer than syncing, not a worse one, and it costs nothing.
The case for sync is narrow and real: you open the same profile from more than one machine, or more than one person needs it, or you want the copy to survive the laptop. If none of those is true for a given profile, leave it local. Pricing has what each plan includes, and the meter is concurrent browsers rather than profile count, so keeping profiles local does not cost you capacity.
Checking it yourself
Launch a name you have never used, without passing sync. Watch for the one-line notice, then check your profile list on the dashboard: the name should not be there. Launch the same name again with sync: true and it should appear.
Then confirm the reverse, which is the case people assume wrongly: take a profile that already syncs, launch it with nothing passed, and check that it still syncs. Default does not mean local. It means unchanged.
Option details are in the SDK docs.
Try it on the free tier.
Unlimited local profiles, no credit card. Check it against the detectors yourself.