diff --git a/apps/desktop/src/components/views/GlobalModalRouter.svelte b/apps/desktop/src/components/views/GlobalModalRouter.svelte index d64e2c3d24..1904d8670a 100644 --- a/apps/desktop/src/components/views/GlobalModalRouter.svelte +++ b/apps/desktop/src/components/views/GlobalModalRouter.svelte @@ -83,6 +83,18 @@ const modalProps = $derived(mapModalStateToProps(uiState.global.modal.current)); + // Svelte 5 can propagate prop changes into the child block before the outer + // {#if} re-evaluates and unmounts it, causing crashes like + // "undefined is not an object (evaluating 'data.projectId')". stableModalData + // latches the last non-null modalProps so the children always see valid data; + // the {#if modalProps && stableModalData} gate handles visibility. + let stableModalData = $state(null); + $effect.pre(() => { + if (modalProps !== null) { + stableModalData = modalProps; + } + }); + let modal = $state(); // Show the modal whenever modalProps becomes truthy. @@ -98,7 +110,7 @@ // If the login confirmation modal is closed without explicit user action (e.g., via ESC), // we should reject the incoming user to maintain state consistency. // We check if there's still an incoming user to avoid calling reject after accept/reject buttons. - if (modalProps?.state.type === "login-confirmation") { + if (stableModalData?.state.type === "login-confirmation") { if (userService.incomingUserLogin) { userService.rejectIncomingUser(); } @@ -121,23 +133,23 @@ } -{#if modalProps} +{#if modalProps && stableModalData} close()} > - {#if modalProps.state.type === "commit-failed"} - - {:else if modalProps.state.type === "author-missing"} - - {:else if modalProps.state.type === "general-settings"} - - {:else if modalProps.state.type === "project-settings"} - - {:else if modalProps.state.type === "login-confirmation"} - + {#if stableModalData.state.type === "commit-failed"} + + {:else if stableModalData.state.type === "author-missing"} + + {:else if stableModalData.state.type === "general-settings"} + + {:else if stableModalData.state.type === "project-settings"} + + {:else if stableModalData.state.type === "login-confirmation"} + {/if} {/if}