{"record":{"id":"49ba88259d0c32c1","repo":"tinyhumansai/openhuman","slug":"artifact-save-dialog-failed-falling-back-to-dow","errorCode":null,"errorMessage":"[artifact] save dialog failed, falling back to Downloads:","messagePattern":"\\[artifact\\] save dialog failed, falling back to Downloads:","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"app/src/services/artifactDownloadService.ts","lineNumber":296,"sourceCode":"  if (!resolved.ok) {\n    return { ok: false, code: resolved.code, error: resolved.error };\n  }\n\n  try {\n    // Command returns the saved path, or `null` when the user cancelled.\n    const dest = await invoke<string | null>('save_artifact_via_dialog', {\n      sourcePath: resolved.sourcePath,\n      suggestedFilename: resolved.filename,\n    });\n    if (dest == null) {\n      return { ok: false, code: 'CANCELLED', error: 'save cancelled by user' };\n    }\n    return { ok: true, path: dest };\n  } catch (err) {\n    // Dialog unavailable (no portal / unsupported) — recover the artifact\n    // via the Downloads copy rather than stranding the user.\n    const reason = err instanceof Error ? err.message : String(err);\n    console.warn('[artifact] save dialog failed, falling back to Downloads:', reason);\n    return downloadArtifact(artifactId, fallbackTitle, extension);\n  }\n}\n\n/**\n * Open the user's file manager pointed at the just-downloaded file.\n * Uses the existing `opener:allow-reveal-item-in-dir` capability —\n * no new permission needed. Returns `false` when not in Tauri or the\n * invoke fails (caller usually ignores the result).\n */\n/**\n * Delete the artifact and its on-disk blob via the core RPC (#3024).\n * Caller is expected to optimistically remove the slice row first and\n * re-insert on `{ ok: false }`. Distinct from the runtime in-memory\n * slice ledger — this drops the file on disk and the persistent\n * `ArtifactMeta` row in the workspace registry.\n *\n * Returns `{ ok: false, error }` on any transport or RPC error","sourceCodeStart":278,"sourceCodeEnd":314,"githubUrl":"https://github.com/tinyhumansai/openhuman/blob/749120085864ce16e0f273c7b86fac7740b39c5b/app/src/services/artifactDownloadService.ts#L278-L314","documentation":"Recovery path in the artifact save flow: the native save_artifact_via_dialog invoke failed (no dialog portal, unsupported platform, or dialog subsystem error), so instead of failing the download the code falls back to writing the artifact into the user's Downloads folder. The warning marks the UX downgrade, not a lost file.","triggerScenarios":"Thrown at app/src/services/artifactDownloadService.ts:296 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Rely on the Downloads fallback — the artifact still lands on disk","On Linux, verify a xdg-desktop-portal implementation is present for native dialogs","Surface the final path in the UI so the user finds the fallback copy"],"exampleFix":null,"handlingStrategy":"fallback","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"749120085864ce16e0f273c7b86fac7740b39c5b","analyzedAt":"2026-08-17T21:21:45.363Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}