209209 < div class ="mount-fallback__panel " tabindex ="-1 ">
210210 < p class ="mount-fallback__eyebrow "> OpenClaw Control UI</ p >
211211 < h1 id ="openclaw-mount-fallback-title "> Control UI did not start</ h1 >
212- < p >
213- The browser loaded the static page, but the app bundle did not register the
214- < code > openclaw-app</ code > web component. A browser extension or early content script may
215- be blocking module execution.
212+ < p id ="openclaw-mount-fallback-summary ">
213+ The browser loaded the static page, but the app bundle did not start. The gateway may be
214+ restarting, or this page may reference assets from a different OpenClaw version.
216215 </ p >
217216 < ul >
218- < li > Try again in a clean browser profile or private window .</ li >
219- < li > Disable extensions that run on all pages, then reload this dashboard .</ li >
217+ < li > OpenClaw will retry the current app bundle automatically .</ li >
218+ < li > If this persists, reload or try a clean browser profile .</ li >
220219 < li >
221220 See
222221 < a
@@ -249,11 +248,26 @@ <h1 id="openclaw-mount-fallback-title">Control UI did not start</h1>
249248 if ( ! app || ! fallback ) return ;
250249
251250 var panel = fallback . querySelector ( ".mount-fallback__panel" ) ;
251+ var summary = document . getElementById ( "openclaw-mount-fallback-summary" ) ;
252252 var retry = document . getElementById ( "openclaw-mount-retry" ) ;
253253 var wait = document . getElementById ( "openclaw-mount-wait" ) ;
254254 var rawDelay = Number ( fallback . getAttribute ( "data-openclaw-mount-timeout-ms" ) ) ;
255255 var delay = Number . isFinite ( rawDelay ) && rawDelay > 0 ? rawDelay : 12000 ;
256+ var maxRecoveryAttempts = 6 ;
256257 var timer ;
258+ var recoveryTimer ;
259+ var recoveryAttempt = 0 ;
260+ var recoveryInFlight = false ;
261+ var recoveryNavigation = false ;
262+
263+ try {
264+ var initialUrl = new URL ( window . location . href ) ;
265+ recoveryNavigation = initialUrl . searchParams . has ( "openclaw_mount_recovery" ) ;
266+ if ( recoveryNavigation ) {
267+ initialUrl . searchParams . delete ( "openclaw_mount_recovery" ) ;
268+ window . history . replaceState ( null , "" , initialUrl . href ) ;
269+ }
270+ } catch ( e ) { }
257271
258272 function appMounted ( ) {
259273 try {
@@ -273,8 +287,64 @@ <h1 id="openclaw-mount-fallback-title">Control UI did not start</h1>
273287 document . body . classList . remove ( "openclaw-mount-fallback-active" ) ;
274288 }
275289
290+ function setSummary ( text ) {
291+ if ( summary ) summary . textContent = text ;
292+ }
293+
294+ function scheduleRecovery ( ) {
295+ window . clearTimeout ( recoveryTimer ) ;
296+ if ( appMounted ( ) || recoveryAttempt >= maxRecoveryAttempts ) return ;
297+ var retryDelay = Math . min ( delay , 1000 * Math . pow ( 2 , recoveryAttempt ) ) ;
298+ recoveryTimer = window . setTimeout ( retryCurrentDocument , retryDelay ) ;
299+ }
300+
301+ function finishRecoveryAttempt ( ) {
302+ recoveryInFlight = false ;
303+ if ( appMounted ( ) ) return ;
304+ if ( recoveryAttempt >= maxRecoveryAttempts ) {
305+ setSummary (
306+ "The gateway is still unavailable. Try again, then check the troubleshooting guide if the problem persists." ,
307+ ) ;
308+ return ;
309+ }
310+ setSummary (
311+ "The gateway is not reachable yet. OpenClaw will keep retrying while it restarts." ,
312+ ) ;
313+ scheduleRecovery ( ) ;
314+ }
315+
316+ function retryCurrentDocument ( ) {
317+ if (
318+ appMounted ( ) ||
319+ recoveryInFlight ||
320+ recoveryAttempt >= maxRecoveryAttempts ||
321+ typeof window . fetch !== "function"
322+ )
323+ return ;
324+ var documentUrl = new URL ( window . location . href ) ;
325+ if ( recoveryNavigation ) {
326+ setSummary (
327+ "A fresh page still could not start the Control UI. Try again, then check the troubleshooting guide if the problem persists." ,
328+ ) ;
329+ return ;
330+ }
331+ recoveryInFlight = true ;
332+ recoveryAttempt += 1 ;
333+ documentUrl . searchParams . set ( "openclaw_mount_recovery" , String ( Date . now ( ) ) ) ;
334+ window
335+ . fetch ( documentUrl . href , { cache : "no-store" , credentials : "same-origin" } )
336+ . then ( function ( response ) {
337+ if ( ! response . ok ) throw new Error ( "gateway unavailable" ) ;
338+ window . location . replace ( documentUrl . href ) ;
339+ } )
340+ . catch ( function ( ) {
341+ finishRecoveryAttempt ( ) ;
342+ } ) ;
343+ }
344+
276345 function showFallback ( ) {
277346 if ( appMounted ( ) ) return ;
347+ retryCurrentDocument ( ) ;
278348 fallback . hidden = false ;
279349 document . body . classList . add ( "openclaw-mount-fallback-active" ) ;
280350 if ( panel && typeof panel . focus === "function" ) {
@@ -297,6 +367,7 @@ <h1 id="openclaw-mount-fallback-title">Control UI did not start</h1>
297367 window . customElements . whenDefined ( tagName ) . then (
298368 function ( ) {
299369 window . clearTimeout ( timer ) ;
370+ window . clearTimeout ( recoveryTimer ) ;
300371 hideFallback ( ) ;
301372 } ,
302373 function ( ) { } ,
@@ -311,6 +382,8 @@ <h1 id="openclaw-mount-fallback-title">Control UI did not start</h1>
311382 if ( wait ) {
312383 wait . addEventListener ( "click" , function ( ) {
313384 hideFallback ( ) ;
385+ recoveryAttempt = 0 ;
386+ retryCurrentDocument ( ) ;
314387 armFallbackTimer ( ) ;
315388 } ) ;
316389 }
0 commit comments