diff --git a/locales/en.json b/locales/en.json index 8439292f..5254cabd 100644 --- a/locales/en.json +++ b/locales/en.json @@ -717,9 +717,9 @@ "adoptPromptVenvBrokenMessage": "The Legacy Desktop Python environment failed to import torch. You can adopt anyway or cancel.", "adoptPromptUseAnyway": "Adopt anyway", "adoptPromptSourceMissingTitle": "ComfyUI source unavailable", - "adoptPromptSourceMissingMessage": "Could not source ComfyUI from the staged copy or git. Switch to a managed environment (full reinstall) or retry.", - "adoptPromptSwitchToManaged": "Switch to managed env", + "adoptPromptSourceMissingMessage": "Couldn't get the ComfyUI source from the staged copy or by downloading it. Retry, or cancel and create a new install instead.", "adoptPromptRetry": "Retry", + "adoptSourceMissingFailed": "Couldn't download the ComfyUI source needed to migrate your Legacy Desktop install. Check your internet connection and try again. If this keeps happening, create a new install from the dashboard instead.", "adoptStepBackup": "Back up legacy state", "adoptStepTcc": "Check folder access", "adoptStepVenv": "Validate Python environment", diff --git a/src/main/lib/desktopAdopt.ts b/src/main/lib/desktopAdopt.ts index 855bd9c5..450b0c74 100644 --- a/src/main/lib/desktopAdopt.ts +++ b/src/main/lib/desktopAdopt.ts @@ -52,7 +52,7 @@ export type AdoptPromptKind = 'tcc' | 'venv-broken' | 'source-missing' | 'confir export type UserChoice = | { kind: 'tcc'; choice: 'continue' | 'denied' } | { kind: 'venv-broken'; choice: 'use-anyway' | 'cancel' } - | { kind: 'source-missing'; choice: 'switch-to-managed' | 'retry' | 'cancel' } + | { kind: 'source-missing'; choice: 'retry' | 'cancel' } | { kind: 'confirm-adopt'; choice: 'yes' | 'no' } export interface AdoptTools { @@ -1025,14 +1025,14 @@ async function runAdoption( message: sourceResult.message, attempts: sourceAttempts }) - if (choice.kind !== 'source-missing') break - if (choice.choice === 'cancel') { + // Only an explicit retry loops. Anything else (cancel, or an + // unexpected choice) is a hard failure: adoption cannot continue + // without the ComfyUI source. Throw a clear error the dispatcher + // surfaces to the user — with a suggestion to do a fresh install — + // rather than silently leaving `sourceMode` null. + if (!(choice.kind === 'source-missing' && choice.choice === 'retry')) { throw new Error(`source-missing: ${sourceResult.message}`) } - if (choice.choice === 'switch-to-managed') { - // Caller (dispatcher) maps this to the fresh-standalone flow. - throw new Error('source-missing-switch-to-managed') - } // 'retry' loops. } diff --git a/src/main/lib/ipc/sessionActions/migrate.test.ts b/src/main/lib/ipc/sessionActions/migrate.test.ts index 1a9b36eb..1d361f0a 100644 --- a/src/main/lib/ipc/sessionActions/migrate.test.ts +++ b/src/main/lib/ipc/sessionActions/migrate.test.ts @@ -88,10 +88,12 @@ describe('handleMigrateToStandalone — desktop branch', () => { }) }) - it('routes "source-missing-switch-to-managed" to new-install navigation', async () => { - adoptDesktopInstallMock.mockRejectedValueOnce(new Error('source-missing-switch-to-managed')) + it('fails clearly when adoption cannot source ComfyUI (no fake-success fallback)', async () => { + adoptDesktopInstallMock.mockRejectedValueOnce( + new Error('source-missing: git clone failed') + ) const result = await handleMigrateToStandalone(makeContext({ sourceId: 'desktop' })) - expect(result).toEqual({ ok: true, navigate: 'new-install' }) + expect(result).toEqual({ ok: false, message: 'desktop.adoptSourceMissingFailed' }) }) it('surfaces other adoption errors as failure results', async () => { diff --git a/src/main/lib/ipc/sessionActions/migrate.ts b/src/main/lib/ipc/sessionActions/migrate.ts index 9d71c0f5..0e9b549c 100644 --- a/src/main/lib/ipc/sessionActions/migrate.ts +++ b/src/main/lib/ipc/sessionActions/migrate.ts @@ -62,18 +62,14 @@ function buildAdoptPromptSpec(kind: AdoptPromptKind, ctx: unknown): PromptSpec { message: i18n.t('desktop.adoptPromptSourceMissingMessage'), detail: typeof data['message'] === 'string' ? (data['message'] as string) : undefined, buttons: [ - { - label: i18n.t('desktop.adoptPromptSwitchToManaged'), - choice: { kind: 'source-missing', choice: 'switch-to-managed' } - }, { label: i18n.t('desktop.adoptPromptRetry'), choice: { kind: 'source-missing', choice: 'retry' } }, { label: i18n.t('common.cancel'), choice: { kind: 'source-missing', choice: 'cancel' } } ], - defaultId: 1, - cancelId: 2 + defaultId: 0, + cancelId: 1 } case 'confirm-adopt': // Only shown if the orchestrator escalates a runtime decision. @@ -167,10 +163,11 @@ export async function handleMigrateToStandalone({ } if (abort.signal.aborted) return { ok: true, navigate: 'detail' } const message = (err as Error).message - // Synthetic error meaning "user picked Switch to managed env" — route to - // the new-install flow instead of a failure dialog. - if (message === 'source-missing-switch-to-managed') { - return { ok: true, navigate: 'new-install' } + // Adoption couldn't obtain the ComfyUI source (no staged copy and the + // git clone failed). Fail clearly with a message that points the user + // at doing a fresh install, rather than the old fake-success no-op. + if (message.startsWith('source-missing')) { + return { ok: false, message: i18n.t('desktop.adoptSourceMissingFailed') } } return { ok: false, message } } diff --git a/src/shared/errorBucket.ts b/src/shared/errorBucket.ts index 5310ffdd..f7fb7dfa 100644 --- a/src/shared/errorBucket.ts +++ b/src/shared/errorBucket.ts @@ -79,12 +79,12 @@ export function bucketError(input: unknown): ErrorBucket { ) { return 'validation' } - // Migration `source` phase — either the legacy ComfyUI tree is gone - // ("source-missing-switch-to-managed") or the replacement clone from - // a git mirror stalled mid-stream ("source-missing: Downloading - // ComfyUI source from …"). Bucketed before `network` because the - // mirror-clone failures also reach a fetch site and would otherwise - // bucket as network. + // Migration `source` phase — adoption couldn't obtain the ComfyUI + // source: the legacy tree is gone and the replacement clone from a git + // mirror also failed ("source-missing: Downloading ComfyUI source + // from …"). Bucketed before `network` because the mirror-clone + // failures also reach a fetch site and would otherwise bucket as + // network. if ( message.includes('source-missing') || message.includes('source_missing') ||