tauri-apps / tauri-apps/plugins-workspace

[bug] Android save dialog renames duplicate files as "file.pdf(1)" instead of "file(1).pdf"

Open Beginner friendly
#3,498 1 comment 0 reactions 0 assignees View on GitHub
platform: android plugin: dialog type: bug
Dominant language
Rust
Stars
1.8k
Forks
602
Avg merge
4d 14h
Merged PRs (30d)
9

Description

### Describe the bug

### Describe the bug

On Android, when saving a file via `@tauri-apps/plugin-dialog`'s `save()`
to a location where a file with the same name already exists, the SAF
(Storage Access Framework) document provider appends the disambiguation
suffix AFTER the full filename instead of before the extension.

Example:
- Expected: `10mb.pdf` → `10mb(1).pdf`
- Actual: `10mb.pdf` → `10mb.pdf(1)`

### Root cause

**File:** `plugins/dialog/android/src/main/java/DialogPlugin.kt`
**Function:** `saveFileDialog()`
**Line:** 207

```kotlin
val intent = Intent(Intent.ACTION_CREATE_DOCUMENT)
intent.addCategory(Intent.CATEGORY_OPENABLE)
intent.putExtra(Intent.EXTRA_TITLE, args.fileName ?: "")
intent.type = "*/*" // ← hardcoded regardless of filters

if (parsedTypes.isNotEmpty()) {
intent.putExtra(Intent.EXTRA_MIME_TYPES, parsedTypes)
}
```

### Reproduction

Call save({ defaultPath: "10mb.pdf", filters: [{ name: "PDF", extensions: ["pdf"] }] }).
Save to a folder that already contains 10mb.pdf.
Observe the resulting file is named 10mb.pdf(1) instead of 10mb(1).pdf.

### Expected behavior

_No response_

### Full `tauri info` output

```text
Use the first parsed filter's MIME type when available, falling back to
the wildcard only when no filters are given:

intent.type = parsedTypes.firstOrNull() ?: "*/*"
I've tested this fix locally (forked build) and confirmed it produces the
correct name(1).ext format on a real device (Pixel 7, Android 14).
```

### Stack trace

```text

```

### Additional context

Use the first parsed filter's MIME type when available, falling back to
the wildcard only when no filters are given:

intent.type = parsedTypes.firstOrNull() ?: "*/*"
I've tested this fix locally (forked build) and confirmed it produces the
correct name(1).ext format on a real device (Pixel 7, Android 14).

Contributor guide

Open the contributing guide

Research direction

Start in plugins/dialog/android/src/main/java/DialogPlugin.kt at saveFileDialog(), around line 207, and inspect how parsedTypes and the Android document intent are used. Reproduce the save operation with a duplicate .pdf and a PDF filter on Android, then verify that duplicate naming places the suffix before the extension while unfiltered saves retain current behavior.

Written by the indexing model from the issue text.

Assessment

Tech stack
android, kotlin
Domain
mobile
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
76/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.