tauri-apps / tauri-apps/plugins-workspace
[notification] init script fires IPC on about:blank → 500 'Origin header is not a valid URL' on Linux (WebKitGTK)
- Dominant language
- Rust
- Stars
- 1.8k
- Forks
- 602
- Avg merge
- 4d 14h
- Merged PRs (30d)
- 9
Description
## Bug
The notification plugin's init script (`init-iife.js`, generated from `guest-js/init.ts`) fires `plugin:notification|is_permission_granted` **eagerly at script injection time** (async IIFE, no `.catch`):
```js
async function(){ ... await invoke("plugin:notification|is_permission_granted") }().then(...)
```
On Linux (WebKitGTK), user scripts at `document-start` can run on the webview's **initial `about:blank` document** before the real navigation commits (timing/race — heavier startup makes it more likely). From `about:blank` the fetch carries an opaque origin:
```
Origin: null
Referer: about:blank
```
Tauri's IPC handler (`crates/tauri/src/ipc/protocol.rs`) requires `Origin` to be a parseable URL, so the request fails with **500 "Origin header is not a valid URL"**, and since the IIFE has no `.catch`, the page logs `Unhandled Promise Rejection`.
Verified by patching tauri to log the raw header on parse failure:
```
invalid Origin header: "null" (relative URL without a base);
request uri: ipc://localhost/plugin%3Anotification%7Cis_permission_granted
```
## Environment
- tauri 2.11.2, tauri-plugin-notification 2.3.3
- WebKitGTK 2.52.4 (NixOS), production build (`tauri://localhost` custom protocol)
- Does not reproduce on macOS (WKWebView timing differs) nor in dev mode (http origin)
## Suggested fix
In `guest-js/init.ts`, skip the eager permission priming when running on `about:blank` (the init script re-runs on the real document after navigation anyway), and add a `.catch` so a failed prime never surfaces as an unhandled rejection:
```js
if (location.href !== 'about:blank') {
primePermission().then(...).catch(() => {})
}
```
Related: tauri-apps/tauri#11504, anomalyco/opencode#8962
Contributor guide
Research direction
Start in guest-js/init.ts and inspect the eager permission-priming call generated into init-iife.js; the IPC failure context is in crates/tauri/src/ipc/protocol.rs. Verify that priming is skipped for about:blank, reruns after real navigation, and failed priming does not produce an unhandled rejection on Linux WebKitGTK.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust, typescript
- Domain
- desktop-dev
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 84/100