Skip to content

[Bug] Panic (Option::unwrap on None in stats.rs:316) when typing certain multi-byte characters as first non-whitespace character of a line #171

Description

@RYSQL

Description

Ferrite reliably crashes (hangs ~1 second, then closes; on relaunch it offers to restore the buffer) when certain characters are typed as the first non-whitespace character of a line. On the next launch, the captured stderr shows a Rust panic:

thread 'main' panicked at src\editor\stats.rs:316:49: called `Option::unwrap()` on a `None` value ​

Environment

  • OS: Windows 11 Enterprise (build 10.0.22631)
  • Ferrite version: 0.3.0
  • Installation method: Windows portable binary (ferrite-portable-windows-x64), located in C:\Apps\
  • Physical keyboard: German layout
  • Configured Windows keyboard layouts: ENG US, DEU German, ENG German
    (the crash occurs while the active layout is DEU German)

Steps to Reproduce

The crash is fully reproducible on my machine.

  1. Make the active Windows keyboard layout DEU German.
  2. In a Ferrite document, place the cursor at the very start of a line.
  3. Type one of the trigger characters listed below as the first non-whitespace character of that line.
  4. Ferrite hangs briefly and then closes.

Trigger characters

All of the following crash Ferrite when they are the first non-whitespace character of a line:

Character How it is produced on a German layout
§ Shift + 3 (this is the # position on a US layout)
´ (acute accent) The dead key left of Backspace — see note below
ß The key right of 0
ö The key right of l
ä The key right of ö

Note on the ´ (acute accent) dead key: This is a dead key. Tapping it once produces nothing; the character is only committed after pressing Space. The crash occurs precisely at the moment Space is pressed to commit the accent. The backtick ` (produced with Shift on the same physical key) does not crash - only the non-shifted acute accent ´ does.

Position dependency (important)

The crash only happens when the trigger character is the first non-whitespace character on the line:

  • ❌ Trigger character at the start of a line → crash
  • ❌ One or more spaces or tabs, then a trigger character → still crashes (leading whitespace does not prevent it)
  • ✅ Any other character first (a letter, a digit, or a symbol such as +), then a trigger character → no crash

Expected Behavior

Typing any of these characters at the start of a line should simply insert the character, as it does everywhere else in the line.

Actual Behavior

  • Ferrite hangs for roughly one second, then the process exits.
  • On the next launch, Ferrite offers to restore the buffer (crash-recovery prompt).
  • Captured stderr contains the panic shown below.

Log Output

Captured by launching Ferrite with stderr redirected to a file
(cmd /c "set RUST_BACKTRACE=full && ferrite.exe 2> ferrite_panic.log").

The lines above the panic are unrelated session-restore warnings from a previous run;
I have redacted the file paths in them, but nothing bug-relevant was changed.

​```
[WARN ferrite::state] Could not restore tab for '.md': The system cannot find the path specified. (os error 3). File may have been moved or deleted.
[WARN ferrite::state] Could not restore tab for '.yaml': The system cannot find the file specified. (os error 2). File may have been moved or deleted.
[WARN ferrite::state] Could not restore tab for '.yaml': The system cannot find the file specified. (os error 2). File may have been moved or deleted.
[WARN epaint::text::fonts] Failed to find replacement characters '◻' or '?'. Will use empty glyph.

thread 'main' (13612) panicked at src\editor\stats.rs:316:49:
called Option::unwrap() on a None value
stack backtrace:
note: Some details are omitted, run with RUST_BACKTRACE=full for a verbose backtrace.
​```

(I can provide a fuller RUST_BACKTRACE=full trace if useful. I have local WER minidumps for each crash but will not attach them, as they may contain the contents of open documents.)

Screenshots

Not applicable (the behaviour is a crash and cannot be shown in a static screenshot).

Regression

Unknown — 0.3.0 is the first version of Ferrite I have used.

Additional Context

The crash exception code recorded by the Windows Event Viewer (Application Error, Event ID 1000) is 0xc0000409, which is the code Rust uses when a panic aborts the process.

Possible root cause

This is what Claude/Opus said, and I don't really understand it, but I'll reproduce it here in case it's useful:

Since the panic is an Option::unwrap() on None at src\editor\stats.rs:316:49,
and the crash fires only when a multi-byte UTF-8 character (§, ´, ß, ö,
ä) is the first non-whitespace character of a line, this looks like the
line/stats logic making an assumption that fails for a non-ASCII leading character —
for example computing a byte/char index or looking up the first significant token
of a line and unwrapping a result that is None for a multi-byte leading character.

Metadata

Metadata

Assignees

No one assigned

    Labels

    0.3.1bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions