tinyhumansai/openhuman · error

[artifact] save dialog failed, falling back to Downloads:

Error message

[artifact] save dialog failed, falling back to Downloads:

What it means

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.

Source

Thrown at app/src/services/artifactDownloadService.ts:296

  if (!resolved.ok) {
    return { ok: false, code: resolved.code, error: resolved.error };
  }

  try {
    // Command returns the saved path, or `null` when the user cancelled.
    const dest = await invoke<string | null>('save_artifact_via_dialog', {
      sourcePath: resolved.sourcePath,
      suggestedFilename: resolved.filename,
    });
    if (dest == null) {
      return { ok: false, code: 'CANCELLED', error: 'save cancelled by user' };
    }
    return { ok: true, path: dest };
  } catch (err) {
    // Dialog unavailable (no portal / unsupported) — recover the artifact
    // via the Downloads copy rather than stranding the user.
    const reason = err instanceof Error ? err.message : String(err);
    console.warn('[artifact] save dialog failed, falling back to Downloads:', reason);
    return downloadArtifact(artifactId, fallbackTitle, extension);
  }
}

/**
 * Open the user's file manager pointed at the just-downloaded file.
 * Uses the existing `opener:allow-reveal-item-in-dir` capability —
 * no new permission needed. Returns `false` when not in Tauri or the
 * invoke fails (caller usually ignores the result).
 */
/**
 * Delete the artifact and its on-disk blob via the core RPC (#3024).
 * Caller is expected to optimistically remove the slice row first and
 * re-insert on `{ ok: false }`. Distinct from the runtime in-memory
 * slice ledger — this drops the file on disk and the persistent
 * `ArtifactMeta` row in the workspace registry.
 *
 * Returns `{ ok: false, error }` on any transport or RPC error

View on GitHub (pinned to 7491200858)

Solutions

  1. Rely on the Downloads fallback — the artifact still lands on disk
  2. On Linux, verify a xdg-desktop-portal implementation is present for native dialogs
  3. Surface the final path in the UI so the user finds the fallback copy
Defensive patterns

Strategy: fallback

When it happens

Trigger: Thrown at app/src/services/artifactDownloadService.ts:296 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of tinyhumansai/openhuman@7491200858 (2026-08-17). Data as JSON: /api/errors/49ba88259d0c32c1. Report an issue: GitHub.