github / github/app

[Bugs] App crashes in a loop on launch (Wry InvalidUri panic).

オープン
#1,171 コメント 1 件 リアクション 0 件 担当者 0 名 GitHub で見る
Bugs
主要言語
言語のデータがありません
スター
2.1k
フォーク
153
PR マージ指標
30日以内にマージされた PR はありません

説明

**Mood:** 😊
**Category:** Bugs

App crashes in a loop on launch (Wry InvalidUri panic).

A persisted "open canvas" reopens a browser canvas on startup with an unescaped
URL. The app calls .unwrap() on http::Uri::try_from(url) inside an extern "C"
WebView2 callback; the URL is invalid (raw spaces from a folder path, and in
another case a # fragment), so it panics with InvalidUri(InvalidFormat). The
panic can't unwind across the FFI boundary -> hard abort (panicking.rs:225). It
recurs every launch and the error popup re-triggers the crash, so the app is
unusable until rows are manually deleted from session_open_canvases in data.db.

Build: copilot-desktop-gh-2.94.0, Wry wry-0.55.1, Windows 11.

Error messages:
called `Result::unwrap()` on an `Err` value: http::Error(InvalidUri(InvalidFormat)) (wry-0.55.1)
panic in a function that cannot unwind (core/src/panicking.rs:225:5)

Suggested fix: percent-encode/normalize URLs before passing to the webview,
don't unwrap() the URI parse, and catch_unwind in the navigation callback.

# Bug Report: App crash loop from persisted canvas with unescaped URL

**Title:** App crash loop: persisted canvas with unescaped URL panics Wry (`InvalidUri(InvalidFormat)`) on launch

**Severity:** High — unrecoverable crash loop; app must be killed and DB hand-edited to recover.

## Environment
- App: GitHub Copilot desktop (`com.github.githubapp`), build `copilot-desktop-gh-2.94.0`
- OS: Windows 11
- WebView: WebView2 (Wry `wry-0.55.1`)

## Summary
Open browser canvases are persisted in `data.db` -> `session_open_canvases` with their
`input.url` stored **unescaped**. When the app reopens such a canvas on launch, it calls
`.unwrap()` on `http::Uri::try_from(url)` inside an `extern "C"` WebView2 navigation
callback. URLs that aren't valid RFC 3986 (raw spaces, or a `#` fragment) fail to parse,
the `unwrap()` panics, and because the panic can't unwind across the FFI boundary it
escalates to a hard abort. This happens **every launch**, producing an unrecoverable loop.

## Two malformed-URL triggers observed
1. **Unescaped spaces** — file URLs built from a path containing spaces were stored
literally, e.g.
`file:///C:/Users///.../dashboard.html`
(note raw spaces, not `%20`).
2. **Fragment URLs** — a single-page-app link (hash-routed) stored as
`https://host/App/#/Displays//...?starttime=...&asset=...`
`http::Uri` rejects the `#` fragment (and the query placed after it).

## Error messages
```
thread '<...>' panicked at wry-0.55.1/.../:
called `Result::unwrap()` on an `Err` value: http::Error(InvalidUri(InvalidFormat))
```
followed by:
```
panic in a function that cannot unwind
core/src/panicking.rs:225:5
```

## Steps to reproduce
1. Open a browser canvas whose URL contains an unescaped space or a `#` fragment.
2. Let it persist to `session_open_canvases` with `reopen: true`.
3. Restart the app -> it reopens the canvas -> Wry panics -> abort.
4. Relaunching repeats the crash (state is persistent).

## Impact
- Crash on startup; the in-app error popup re-triggers the abort when clicked.
- Canvas panel can't be closed because the app aborts first.
- Only recovery is killing all processes and deleting the offending rows from `data.db`
directly.

## Expected behavior
- URLs should be percent-encoded / normalized before being handed to the webview.
- The `http::Uri` parse must not `unwrap()` — handle `Err` gracefully (skip / restore-blank
the canvas, log, surface a non-fatal toast).
- Never let a panic cross the `extern "C"` webview callback (catch at the FFI boundary).

## Suggested fixes
1. Replace `http::Uri::try_from(url).unwrap()` with proper error handling at the navigation
call site.
2. Encode URLs when persisting/loading canvas `input.url` (e.g. `Url::parse` /
percent-encoding) so spaces and fragments are valid.
3. Wrap the WebView2 navigation callback body in `std::panic::catch_unwind` so a bad URL
degrades gracefully instead of aborting.
4. Validate `session_open_canvases.input.url` on load; drop/repair entries that don't parse.

## Workaround for affected users
Fully close the app, then delete rows from `session_open_canvases` in
`%USERPROFILE%\.copilot\data.db` (back it up first).

---
| Field | Value |
| --- | --- |
| App version | 1.0.1 |
| OS | Windows 10.0.26200 |
| Theme | GitHub |
| Path | /chat |
| Tenure | Day 1 |

コントリビューションガイド

コントリビューションガイドを開く

調査の方向性

Start at the WebView2 navigation callback and its http::Uri::try_from(url).unwrap() call site; inspect how session_open_canvases URLs are loaded and persisted. Reproduce with a URL containing a space or #, then verify invalid entries no longer abort launch or require database deletion while valid canvases still reopen.

索引モデルが issue の本文から書いたものです。

評価

技術スタック
rust
領域
desktop
issue の種類
バグ
難易度
4/5
見積もり時間
3〜5日
活発さ
静か
明瞭さ
おおむね明確
初心者へのやさしさ
45/100

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。