I don't fully understand all the implications or how it works, but yes this is kind of the normal intended behavior. As CARTO generates map tiles (Windshaft), they get cached on a CDN (in the
carto.com cloud accounts) or in Varnish (open source) under an ephemeral map configuration token (aka layergroupid, I'm pretty sure). The cache is purged/invalidated every so often when there's no continued activity on a map, so "a few hours" sitting still with no user interaction fits the bill. The in-memory Javascript variables in a browser tab of a map that has been open that long will still be set to the old token describing the cache location, but it doesn't exist anymore on the server once purged, hence this error. And why refreshing the map takes care of it easy, because on refresh the map is re-instantiated and a new cache is created.
A tip to work-around this behavior if you're developing an application (and not a Builder map) might be to try this tile access method with Named maps instead:
https://carto.com/developers/maps-api/guides/named-maps/#fetching-xyz-tiles-for-named-maps You'd have to use the more traditional "XYZ" layer fetching functionality of whatever base mapping library you use (L.tileLayer(), for example), instead of any CARTO.js / CARTO VL feature (neither of the SDKs have any Named map access features). But the Named map name should never change and those tiles should always be present at that location, even hours/nights/days later of a continuously open browser tab.