Skip to content

Fix --tail panic on undecryptable events#208

Merged
Benjamin-Loison merged 1 commit into
8go:mainfrom
macalinao:fix-tail-panic
Jun 24, 2026
Merged

Fix --tail panic on undecryptable events#208
Benjamin-Loison merged 1 commit into
8go:mainfrom
macalinao:fix-tail-panic

Conversation

@macalinao

Copy link
Copy Markdown
Contributor

listen_tail() assumed every fetched timeline event was a Decrypted
variant and called panic!() for anything else (src/listen.rs:684). A
single unable-to-decrypt (UTD) or plaintext event in the tail window
therefore crashes the whole program.

This happens routinely on a verified device that is missing the room key for
some older event (e.g. a megolm session that was never in the key backup):

$ matrix-commander-rs --tail 8 --room '!room:server'
Message: type Text: body "...", ...
thread 'main' panicked at src/listen.rs:684:17:
explicit panic

Handle the non-Decrypted case gracefully instead: print a notice (in text
form, or the raw JSON for --output json), count it toward err_count, and
continue with the next event. --tail now prints what it can and skips what
it cannot decrypt.

listen_tail() assumed every timeline event was a Decrypted variant and
called panic!() for anything else. A single unable-to-decrypt (UTD) or
plaintext event in the tail window therefore crashed the whole program.

Handle the non-Decrypted case gracefully instead: print a notice (in the
same style as the messages() RoomEncrypted branch for text output, or the
raw JSON for --output json), count it toward err_count, and continue with
the next event.
@kcexn

kcexn commented Jun 24, 2026

Copy link
Copy Markdown
Contributor

@macalinao Since you're already looking at this. Do you think you could add support for plain text events when tailing? I have a use-case where I'd like to use matrix-commander-rs to administer a Tuwunel homeserver on the host via the built-in (unencrypted) admin room.

@Benjamin-Loison

Benjamin-Loison commented Jun 24, 2026

Copy link
Copy Markdown
Collaborator

I do not notice any string typo and the code seems to quickly make sense.

I am testing these changes.

Improve_websites_thanks_to_open_source/issues/3771 would have helped.

@Benjamin-Loison

Benjamin-Loison commented Jun 24, 2026

Copy link
Copy Markdown
Collaborator

@macalinao Any reason to use unwrap_or_default instead of unwrap?

Personal notes:

Before this pull request:

cargo run -- --tail
Output:
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.27s
     Running `target/debug/matrix-commander-rs --tail`
error: a value is required for '--tail <TAIL>' but none was supplied
cargo run -- --tail 1
Output:
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.27s
     Running `target/debug/matrix-commander-rs --tail 1`
echo $?
0
cargo run -- --tail 1 --room '!sNARMdEsFZERaQAJzl:matrix.org'
Output:
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.27s
     Running `target/debug/matrix-commander-rs --tail 1 --room ''\!'sNARMdEsFZERaQAJzl:matrix.org'`
Message: type Text: body "c", room "!sNARMdEsFZERaQAJzl:matrix.org", sender "@benjamin_loison:matrix.org", event id "$2CGM1oUriVNr-RcleAFnKlVpaFhjizdopvrW8236cLM", formatted None,

It seems that I had to start typing on my receiver side for the command to emit and stop.

cargo run -- --tail 20 --room '!sNARMdEsFZERaQAJzl:matrix.org'
Output:
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.28s
     Running `target/debug/matrix-commander-rs --tail 20 --room ''\!'sNARMdEsFZERaQAJzl:matrix.org'`

thread 'main' (384276) panicked at src/listen.rs:684:17:
explicit panic
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

--room is not necessary to reproduce the issue and the wanted behavior.

With this pull request changes:

cargo run -- --tail 20
Output:
   Compiling matrix-commander v1.0.1 (/home/ubuntu/matrix-commander-rs)
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 25.99s
     Running `target/debug/matrix-commander-rs --tail 20`
Message: type Encrypted: room "!sNARMdEsFZERaQAJzl:matrix.org", sender "@overclock3000:matrix.org", event_id "$MeBYv1xgfSJ9h1FLFoqRIldjpiNUm1Ahc72ZN4hGpBk", message could not be decrypted
Message: type Encrypted: room "!sNARMdEsFZERaQAJzl:matrix.org", sender "@overclock3000:matrix.org", event_id "$EVBodDnk_KA65gPOneqdw0Rzw8DN1-2WlBCAMhhdJjE", message could not be decrypted
Message: type Encrypted: room "!sNARMdEsFZERaQAJzl:matrix.org", sender "@benjamin_loison:matrix.org", event_id "$gC_umVkXT4IrnI2cZtOwDgHRx5BxZ3SyTrlkkMkWm0o", message could not be decrypted
Message: type Encrypted: room "!sNARMdEsFZERaQAJzl:matrix.org", sender "@benjamin_loison:matrix.org", event_id "$xFzqRlw6MYKNOrprWhNyP2pKC6vY95fdavZ1UCQJLl4", message could not be decrypted
Message: type Encrypted: room "!sNARMdEsFZERaQAJzl:matrix.org", sender "@benjamin_loison:matrix.org", event_id "$N4opf7pYH_efkTrKx5CWusawzlffsNYg6v4N-L8ohB8", message could not be decrypted
Message: type Encrypted: room "!sNARMdEsFZERaQAJzl:matrix.org", sender "@overclock3000:matrix.org", event_id "$D23cWkuXZqe8v-_4b2pzWyU5SVF4fHpVfGfJouiZiAc", message could not be decrypted
Message: type Encrypted: room "!sNARMdEsFZERaQAJzl:matrix.org", sender "@benjamin_loison:matrix.org", event_id "$WiADAB8d9-eXSh6QfRPcArc0ARjMKxWmxZ3FFfZkbXU", message could not be decrypted
Message: type Text: body "C", room "!sNARMdEsFZERaQAJzl:matrix.org", sender "@benjamin_loison:matrix.org", event id "$tRFx-UDQlk7cmeJtzeUAbXy303xdTtdrHJwaQtfO-JA", formatted None, 
Message: type Text: body "c", room "!sNARMdEsFZERaQAJzl:matrix.org", sender "@benjamin_loison:matrix.org", event id "$2CGM1oUriVNr-RcleAFnKlVpaFhjizdopvrW8236cLM", formatted None, 
2026-06-24T19:34:41.739310Z ERROR matrix_commander_rs: Error: crate::listen_tail reported Not Implemented Yet
2026-06-24T19:34:41.740971Z ERROR matrix_commander_rs: Encountered 1 error.
Error: NotImplementedYet

Have to check #209 before merging due to:

files#diff-624021025ebdbf037d011a86160f2bd2bb2d97cea072753a5dae9526c580cafcR688-R690

DuckDuckGo search unwrap_or_default.

https://doc.rust-lang.org/std/option/enum.Option.html#method.unwrap_or_default

cargo run -- --tail 16 --output json
Output:
...
{"content":{"body":"From LemnosLife VPS `/var/www/notify.py`: benjamin-loison-framework benjamin_loison -c PERCENT=$(df -h / | tail -n 1 | tr -s   | cut -d   -f5 | sed s/%//g); if [[ $PERCENT -ge 98 ]]; then echo Running out of storage!; fi 0 Running out of storage!","msgtype":"m.text"},"event_id":"$2q40I0EHzlsrWbdnFF3JdjusYeemwKCaPUr-NMOkUG0","origin_server_ts":1782327614122,"room_id":"!sNARMdEsFZERaQAJzl:matrix.org","sender":"@overclock3000:matrix.org","type":"m.room.message","unsigned":{"age":2474039,"membership":"join"}}
{"content":{"body":"a","msgtype":"m.text"},"event_id":"$J-DfDZLUPwn2Cyc5SsO5U_Y0e6B7xeN7aPnKDrK3cz8","origin_server_ts":1782329336128,"room_id":"!sNARMdEsFZERaQAJzl:matrix.org","sender":"@overclock3000:matrix.org","type":"m.room.message","unsigned":{"age":752033,"membership":"join","transaction_id":"9a252dc851034d36ab0ed0762cdc7ffd"}}
{"content":{"body":"b","msgtype":"m.text"},"event_id":"$CyehA32Ye9M2ZZj91Hg_3eLNdFmipmXcAjKKctpJBzQ","origin_server_ts":1782329346528,"room_id":"!sNARMdEsFZERaQAJzl:matrix.org","sender":"@overclock3000:matrix.org","type":"m.room.message","unsigned":{"age":741633,"membership":"join","transaction_id":"20258afcabf845df8b015967f587436d"}}
{"content":{"body":"c","m.mentions":{},"msgtype":"m.text"},"event_id":"$2CGM1oUriVNr-RcleAFnKlVpaFhjizdopvrW8236cLM","origin_server_ts":1782329500725,"room_id":"!sNARMdEsFZERaQAJzl:matrix.org","sender":"@benjamin_loison:matrix.org","type":"m.room.message","unsigned":{"age":587436,"membership":"join"}}
2026-06-24T19:41:28.237789Z ERROR matrix_commander_rs: Error: crate::listen_tail reported Not Implemented Yet
2026-06-24T19:41:28.239469Z ERROR matrix_commander_rs: Encountered 1 error.
Error: NotImplementedYet

Unclear why I have Benjamin-Loison/element-android/issues/65 on my Fairphone 4 LineageOS 23.2 and Linux Mint 22.3 Cinnamon Framework 13, especially as this is not this matrix-commander-rs which sent this encrypted message, but it retrieves it correctly for the first one, but not without --output json.

DuckDuckGo search TimelineEventKind.

cargo run -- --tail 16 --output json --log-level debug
Output:
...
2026-06-24T21:04:32.451561Z DEBUG matrix_commander_rs::listen: rawevent = value is Raw::<ruma_events::enums::AnyTimelineEvent> { json: RawValue({"content":{"body":"From LemnosLife VPS `/var/www/notify.py`: benjamin-loison-framework benjamin_loison -c PERCENT=$(df -h / | tail -n 1 | tr -s   | cut -d   -f5 | sed s/%//g); if [[ $PERCENT -ge 98 ]]; then echo Running out of storage!; fi 0 Running out of storage!","msgtype":"m.text"},"event_id":"$2q40I0EHzlsrWbdnFF3JdjusYeemwKCaPUr-NMOkUG0","origin_server_ts":1782327614122,"room_id":"!sNARMdEsFZERaQAJzl:matrix.org","sender":"@overclock3000:matrix.org","type":"m.room.message","unsigned":{"age":7458252,"membership":"join"}}) }

{"content":{"body":"From LemnosLife VPS `/var/www/notify.py`: benjamin-loison-framework benjamin_loison -c PERCENT=$(df -h / | tail -n 1 | tr -s   | cut -d   -f5 | sed s/%//g); if [[ $PERCENT -ge 98 ]]; then echo Running out of storage!; fi 0 Running out of storage!","msgtype":"m.text"},"event_id":"$2q40I0EHzlsrWbdnFF3JdjusYeemwKCaPUr-NMOkUG0","origin_server_ts":1782327614122,"room_id":"!sNARMdEsFZERaQAJzl:matrix.org","sender":"@overclock3000:matrix.org","type":"m.room.message","unsigned":{"age":7458252,"membership":"join"}}
2026-06-24T21:04:32.451625Z DEBUG matrix_commander_rs::listen: processing message 14 out of 16
2026-06-24T21:04:32.451641Z DEBUG matrix_commander_rs::listen: rawevent = value is Raw::<ruma_events::enums::AnyTimelineEvent> { json: RawValue({"content":{"body":"a","msgtype":"m.text"},"event_id":"$J-DfDZLUPwn2Cyc5SsO5U_Y0e6B7xeN7aPnKDrK3cz8","origin_server_ts":1782329336128,"room_id":"!sNARMdEsFZERaQAJzl:matrix.org","sender":"@overclock3000:matrix.org","type":"m.room.message","unsigned":{"age":5736246,"membership":"join","transaction_id":"9a252dc851034d36ab0ed0762cdc7ffd"}}) }

{"content":{"body":"a","msgtype":"m.text"},"event_id":"$J-DfDZLUPwn2Cyc5SsO5U_Y0e6B7xeN7aPnKDrK3cz8","origin_server_ts":1782329336128,"room_id":"!sNARMdEsFZERaQAJzl:matrix.org","sender":"@overclock3000:matrix.org","type":"m.room.message","unsigned":{"age":5736246,"membership":"join","transaction_id":"9a252dc851034d36ab0ed0762cdc7ffd"}}
...

DuckDuckGo and Google search AnyTimelineEvent.

https://docs.rs/ruma-events/latest/ruma_events/enum.AnyTimelineEvent.html

DuckDuckGo search room chunk matrix sdk.

https://docs.rs/matrix-sdk/0.18.0/matrix_sdk/room/struct.Room.html

https://docs.rs/matrix-sdk/0.18.0/matrix_sdk/room/struct.Messages.html

https://docs.rs/matrix-sdk/0.18.0/matrix_sdk/deserialized_responses/struct.TimelineEvent.html

cargo run -- --tail 16 --output json --log-level debug
Output:
   Compiling matrix-commander v1.0.1 (/home/ubuntu/matrix-commander-rs)
error[E0164]: expected tuple struct or tuple variant, found struct variant `TimelineEventKind::PlainText`
   --> src/listen.rs:684:24
    |
684 |                 if let TimelineEventKind::PlainText(plaintext) = &anytimelineevent.kind {
    |                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not a tuple struct or tuple variant
    |
help: the struct variant's field is being ignored
    |
684 -                 if let TimelineEventKind::PlainText(plaintext) = &anytimelineevent.kind {
684 +                 if let TimelineEventKind::PlainText { event: _ } = &anytimelineevent.kind {
    |

For more information about this error, try `rustc --explain E0164`.
error: could not compile `matrix-commander` (bin "matrix-commander-rs") due to 1 previous error

Note:

DEBUG matrix_commander_rs::listen: Skipping message from itself because --listen-self is not set.

@Benjamin-Loison

Copy link
Copy Markdown
Collaborator

As my tests look concluding, I merge now and you are free to answer my question thank you for the contribution @macalinao!

@Benjamin-Loison
Benjamin-Loison merged commit 6c48a37 into 8go:main Jun 24, 2026
1 check passed
@8go

8go commented Jul 2, 2026

Copy link
Copy Markdown
Owner

Thank you @macalinao. Your PR is appreciated! ❤️

@8go

8go commented Jul 2, 2026

Copy link
Copy Markdown
Owner

thank you @Benjamin-Loison for merging 👏 and being so active!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants