Pyrefly Crashes During Find/Replace In VS Code

by SLV Team 47 views
Pyrefly Crash: 'assertion failed: inserted' Error

Hey guys, I'm here to share a frustrating issue I ran into while using Pyrefly in VS Code. I encountered a panic that caused the extension to crash. Let's dive into the details, including the error message, my setup, and the steps I took.

The Bug: Assertion Failed

So, what happened? I was performing a series of find and replace operations across a bunch of Python files (around 250 of them) in my VS Code project. Suddenly, the extension crashed with the following error message:

ERROR Thread panicked, shutting down: panicked at pyrefly/lib/state/state.rs:1633:17:
assertion failed: inserted
Backtrace:
   0: std::sync::poison::once::Once::call_once::{{closure}}
   1: std::sys::sync::once::futex::Once::call
   2: pyrefly_util::panic::print_panic
   3: pyrefly_util::panic::exit_on_panic::{{closure}}
   4: std::panicking::rust_panic_with_hook
   5: std::panicking::begin_panic_handler::{{closure}}
   6: std::sys::backtrace::__rust_end_short_backtrace
   7: __rustc::rust_begin_unwind
   8: core::panicking::panic_fmt
   9: core::panicking::panic
  10: pyrefly::state::state::TransactionHandle::get_module
  11: <pyrefly::state::state::TransactionHandle as pyrefly::export::exports::LookupExport>::get
  12: pyrefly::binding::stmt::<impl pyrefly::binding::bindings::BindingsBuilder>::stmt
  13: pyrefly::state::steps::Step::step_answers
  14: core::ops::function::FnOnce::call_once{{vtable.shim}}
  15: pyrefly::state::state::Transaction::demand
  16: pyrefly::state::state::Transaction::run_step::{{closure}}
  17: <rayon_core::job::HeapJob<BODY> as rayon_core::job::Job>::execute
  18: rayon_core::registry::WorkerThread::wait_until_cold
  19: std::sys::backtrace::__rust_begin_short_backtrace
  20: core::ops::function::FnOnce::call_once{{vtable.shim}}
  21: std::sys::pal::unix::thread::Thread::new::thread_start

This error indicates that an assertion within the Pyrefly code failed, which means something unexpected happened during the execution. It seems like the issue is related to TransactionHandle::get_module within the pyrefly::state::state module. The backtrace provides a stack of function calls leading up to the crash, helping the developers pinpoint the exact location of the error. In simple terms, while Pyrefly was trying to insert something, it failed to do so, triggering the assertion failure and causing the crash. It looks like the issue happens during the process of getting or handling modules, which is crucial for code analysis and refactoring. The error message is pretty clear, but the root cause requires deeper investigation by the Pyrefly developers.

I was using Pyrefly to perform a bulk find and replace operation, which involves scanning and modifying multiple files. This kind of operation could potentially expose concurrency issues or unexpected states, which might have led to this assertion failure. The detailed backtrace will assist the developers in understanding the context in which the crash occurred, and it is likely they will be able to replicate and resolve the issue.

My Setup: Configuration and Environment

Here's a look at my Pyrefly and VS Code setup at the time of the crash. Knowing the configuration can often help in reproducing and understanding the issue. I have included my Pyrefly settings below so you can see how I had things configured:

"python.pyrefly.disableLanguageServices": true,
"python.pyrefly.displayTypeErrors": "force-on",

I had disabled language services. This setting disables many of the features provided by the language server. I also had type errors forced on, which means the extension would display any type errors it found. It is possible that these settings, in combination with the find and replace operations, might have triggered a specific code path that led to the crash. My extension version was 0.39.2. Including the extension version is critical because it helps identify the specific code version that caused the problem.

Additionally, here is some information on my workspace: I was working on a project with approximately 250 Python files in a VS Code project. The workspace was running on Linux. It is worth noting the size of the project and the operating system because these factors can sometimes influence the occurrence of certain issues. The LSP server logs provide further context.

Investigating the Issue: The LSP Server Logs

The LSP (Language Server Protocol) server logs provide detailed information about the interactions between VS Code and the Pyrefly extension. By examining the logs, we can gain insights into the requests, responses, and any errors that occurred during the find and replace operation that caused the crash. Below is a snippet of the LSP server log, including the requests and interactions just before the crash.

starting generic LSP server
Reading messages
Populating all files in the config (File("/home/user/Desktop/backup/pyproject.toml")).
Request pyrefly/textDocument/typeErrorDisplayStatus (1) is canceled due to subsequent mutation
Handling non-canceled request textDocument/documentSymbol (2)
Handling non-canceled request textDocument/codeAction (3)
Skipping request - language services disabled
Handling non-canceled request textDocument/inlayHint (4)
Skipping request - language services disabled
Unhandled notification: Notification { method: "$/setTrace", params: Object {"value": String("off")} }
Handling non-canceled request pyrefly/textDocument/typeErrorDisplayStatus (5)
Handling non-canceled request pyrefly/textDocument/typeErrorDisplayStatus (6)
Prepare to check 2167 files.
Handling non-canceled request textDocument/documentSymbol (7)
Handling non-canceled request textDocument/semanticTokens/range (8)
Skipping request - language services disabled
Handling non-canceled request textDocument/semanticTokens/full (9)
Skipping request - language services disabled
Populated all files in the project path.
Populating up to 2000 files in the workspace ("/home/user/Desktop/backup").
Prepare to check 4825 files.
Handling non-canceled request textDocument/hover (10)
Skipping request - language services disabled
Handling non-canceled request textDocument/hover (11)
Skipping request - language services disabled
Handling non-canceled request textDocument/hover (12)
Skipping request - language services disabled
Populated all files in the workspace.
Handling non-canceled request textDocument/documentHighlight (13)
Skipping request - language services disabled
Handling non-canceled request textDocument/codeAction (14)
Skipping request - language services disabled
Handling non-canceled request textDocument/codeAction (15)
Skipping request - language services disabled
Handling non-canceled request textDocument/codeAction (16)
Skipping request - language services disabled
Handling non-canceled request textDocument/codeAction (17)
Skipping request - language services disabled
Handling non-canceled request textDocument/completion (18)
Skipping request - language services disabled
Handling non-canceled request textDocument/inlayHint (19)
Skipping request - language services disabled
Handling non-canceled request textDocument/semanticTokens/full (20)
Skipping request - language services disabled
Handling non-canceled request textDocument/codeAction (21)
Skipping request - language services disabled
Handling non-canceled request textDocument/documentSymbol (22)
Handling non-canceled request textDocument/documentSymbol (23)
Handling non-canceled request textDocument/inlayHint (24)
Skipping request - language services disabled
Handling non-canceled request textDocument/codeAction (25)
Skipping request - language services disabled
Handling non-canceled request textDocument/codeAction (26)
Skipping request - language services disabled
Handling non-canceled request textDocument/hover (27)
Skipping request - language services disabled
Handling non-canceled request textDocument/documentHighlight (28)
Skipping request - language services disabled
Handling non-canceled request textDocument/codeAction (29)
Skipping request - language services disabled
Handling non-canceled request textDocument/inlayHint (30)
Skipping request - language services disabled
Handling non-canceled request textDocument/semanticTokens/full (31)
Skipping request - language services disabled
Handling non-canceled request textDocument/documentSymbol (32)
Handling non-canceled request textDocument/documentSymbol (33)
Handling non-canceled request textDocument/codeAction (34)
Skipping request - language services disabled
Handling non-canceled request textDocument/inlayHint (35)
Skipping request - language services disabled
Handling non-canceled request textDocument/documentHighlight (36)
Skipping request - language services disabled
Handling non-canceled request textDocument/inlayHint (37)
Skipping request - language services disabled
Handling non-canceled request textDocument/codeAction (38)
Skipping request - language services disabled
Handling non-canceled request textDocument/semanticTokens/full (39)
Skipping request - language services disabled
Handling non-canceled request textDocument/documentSymbol (40)
Handling non-canceled request textDocument/documentSymbol (41)
Handling non-canceled request textDocument/inlayHint (42)
Skipping request - language services disabled
Handling non-canceled request textDocument/documentHighlight (43)
Skipping request - language services disabled
Handling non-canceled request textDocument/inlayHint (44)
Skipping request - language services disabled
Handling non-canceled request textDocument/inlayHint (45)
Skipping request - language services disabled
Handling non-canceled request textDocument/inlayHint (46)
Skipping request - language services disabled
Handling non-canceled request textDocument/inlayHint (47)
Skipping request - language services disabled
Handling non-canceled request textDocument/documentHighlight (48)
Skipping request - language services disabled
Handling non-canceled request textDocument/codeAction (49)
Skipping request - language services disabled
Handling non-canceled request textDocument/hover (50)
Skipping request - language services disabled
Handling non-canceled request textDocument/inlayHint (51)
Skipping request - language services disabled
Handling non-canceled request textDocument/semanticTokens/full (52)
Skipping request - language services disabled
Handling non-canceled request textDocument/documentSymbol (53)
Handling non-canceled request textDocument/documentSymbol (54)
Handling non-canceled request textDocument/documentHighlight (55)
Skipping request - language services disabled
Handling non-canceled request textDocument/documentHighlight (56)
Skipping request - language services disabled
Handling non-canceled request textDocument/inlayHint (57)
Skipping request - language services disabled
Handling non-canceled request textDocument/documentHighlight (58)
Skipping request - language services disabled
Handling non-canceled request textDocument/documentHighlight (59)
Skipping request - language services disabled
Handling non-canceled request textDocument/codeAction (60)
Skipping request - language services disabled
Handling non-canceled request textDocument/documentHighlight (61)
Skipping request - language services disabled
Handling non-canceled request textDocument/codeAction (62)
Skipping request - language services disabled
Handling non-canceled request textDocument/inlayHint (63)
Skipping request - language services disabled
Handling non-canceled request textDocument/documentHighlight (64)
Skipping request - language services disabled
Handling non-canceled request textDocument/semanticTokens/full (65)
Skipping request - language services disabled
Handling non-canceled request textDocument/documentSymbol (66)
Handling non-canceled request textDocument/documentSymbol (67)
Handling non-canceled request textDocument/inlayHint (68)
Skipping request - language services disabled
Handling non-canceled request textDocument/codeAction (69)
Skipping request - language services disabled
Handling non-canceled request textDocument/documentHighlight (70)
Skipping request - language services disabled
Handling non-canceled request textDocument/codeAction (71)
Skipping request - language services disabled
Handling non-canceled request textDocument/inlayHint (72)
Skipping request - language services disabled
Handling non-canceled request textDocument/codeAction (73)
Skipping request - language services disabled
Handling non-canceled request textDocument/semanticTokens/full (74)
Skipping request - language services disabled
Handling non-canceled request textDocument/documentSymbol (75)
Handling non-canceled request textDocument/documentSymbol (76)
Handling non-canceled request textDocument/documentHighlight (77)
Skipping request - language services disabled
Handling non-canceled request textDocument/inlayHint (78)
Skipping request - language services disabled
Handling non-canceled request textDocument/documentHighlight (79)
Skipping request - language services disabled
Handling non-canceled request textDocument/documentHighlight (80)
Skipping request - language services disabled
Handling non-canceled request textDocument/codeAction (81)
Skipping request - language services disabled
Handling non-canceled request textDocument/inlayHint (82)
Skipping request - language services disabled
Handling non-canceled request textDocument/documentHighlight (83)
Skipping request - language services disabled
Handling non-canceled request textDocument/semanticTokens/full (84)
Skipping request - language services disabled
Handling non-canceled request textDocument/documentSymbol (85)
Handling non-canceled request textDocument/documentSymbol (86)
Handling non-canceled request textDocument/codeAction (87)
Skipping request - language services disabled
Handling non-canceled request textDocument/inlayHint (88)
Skipping request - language services disabled
Handling non-canceled request textDocument/codeAction (89)
Skipping request - language services disabled
Handling non-canceled request textDocument/semanticTokens/full (90)
Skipping request - language services disabled
Handling non-canceled request textDocument/documentSymbol (91)
Handling non-canceled request textDocument/documentSymbol (92)
Handling non-canceled request textDocument/inlayHint (93)
Skipping request - language services disabled
Handling non-canceled request textDocument/hover (94)
Skipping request - language services disabled
Handling non-canceled request textDocument/inlayHint (95)
Skipping request - language services disabled
Handling non-canceled request textDocument/inlayHint (96)
Skipping request - language services disabled
Handling non-canceled request textDocument/inlayHint (97)
Skipping request - language services disabled
Handling non-canceled request textDocument/inlayHint (98)
Skipping request - language services disabled
Handling non-canceled request textDocument/inlayHint (99)
Skipping request - language services disabled
Handling non-canceled request textDocument/inlayHint (100)
Skipping request - language services disabled
Handling non-canceled request textDocument/inlayHint (101)
Skipping request - language services disabled
Handling non-canceled request textDocument/documentHighlight (102)
Skipping request - language services disabled
Handling non-canceled request textDocument/codeAction (103)
Skipping request - language services disabled
Handling non-canceled request textDocument/documentHighlight (104)
Skipping request - language services disabled
Handling non-canceled request textDocument/codeAction (105)
Skipping request - language services disabled
Handling non-canceled request textDocument/inlayHint (106)
Skipping request - language services disabled
Handling non-canceled request textDocument/codeAction (107)
Skipping request - language services disabled
Handling non-canceled request textDocument/semanticTokens/full (108)
Skipping request - language services disabled
Handling non-canceled request textDocument/documentSymbol (109)
Handling non-canceled request textDocument/documentSymbol (110)
Handling non-canceled request textDocument/inlayHint (111)
Skipping request - language services disabled
Handling non-canceled request textDocument/inlayHint (112)
Skipping request - language services disabled
Handling non-canceled request textDocument/documentHighlight (113)
Skipping request - language services disabled
Handling non-canceled request textDocument/codeAction (114)
Skipping request - language services disabled
Handling non-canceled request textDocument/documentHighlight (115)
Skipping request - language services disabled
Handling non-canceled request textDocument/codeAction (116)
Skipping request - language services disabled
Handling non-canceled request textDocument/inlayHint (117)
Skipping request - language services disabled
Handling non-canceled request textDocument/codeAction (118)
Skipping request - language services disabled
Handling non-canceled request textDocument/semanticTokens/full (119)
Skipping request - language services disabled
Handling non-canceled request textDocument/documentSymbol (120)
Handling non-canceled request textDocument/documentSymbol (121)
Handling non-canceled request textDocument/inlayHint (122)
Skipping request - language services disabled
Handling non-canceled request textDocument/inlayHint (123)
Skipping request - language services disabled
Handling non-canceled request textDocument/hover (124)
Skipping request - language services disabled
Handling non-canceled request textDocument/documentHighlight (125)
Skipping request - language services disabled
Handling non-canceled request textDocument/documentHighlight (126)
Skipping request - language services disabled
Handling non-canceled request textDocument/codeAction (127)
Skipping request - language services disabled
Handling non-canceled request textDocument/inlayHint (128)
Skipping request - language services disabled
Handling non-canceled request textDocument/codeAction (129)
Skipping request - language services disabled
Handling non-canceled request textDocument/semanticTokens/full (130)
Skipping request - language services disabled
Handling non-canceled request textDocument/documentSymbol (131)
Handling non-canceled request textDocument/documentSymbol (132)
Handling non-canceled request textDocument/inlayHint (133)
Skipping request - language services disabled
Handling non-canceled request textDocument/inlayHint (134)
Skipping request - language services disabled
Handling non-canceled request textDocument/documentHighlight (135)
Skipping request - language services disabled
Handling non-canceled request textDocument/codeAction (136)
Skipping request - language services disabled
Handling non-canceled request textDocument/documentHighlight (137)
Skipping request - language services disabled
Handling non-canceled request textDocument/codeAction (138)
Skipping request - language services disabled
Handling non-canceled request textDocument/inlayHint (139)
Skipping request - language services disabled
Handling non-canceled request textDocument/codeAction (140)
Skipping request - language services disabled
Handling non-canceled request textDocument/semanticTokens/full (141)
Skipping request - language services disabled
Handling non-canceled request textDocument/documentSymbol (142)
Handling non-canceled request textDocument/documentSymbol (143)
Handling non-canceled request textDocument/inlayHint (144)
Skipping request - language services disabled
Handling non-canceled request textDocument/inlayHint (145)
Skipping request - language services disabled
Handling non-canceled request textDocument/hover (146)
Skipping request - language services disabled
Handling non-canceled request textDocument/documentHighlight (147)
Skipping request - language services disabled
Handling non-canceled request textDocument/documentHighlight (148)
Skipping request - language services disabled
Populating all files in the config (File("/home/user/Desktop/backup/pyproject.toml")).
Handling non-canceled request pyrefly/textDocument/typeErrorDisplayStatus (149)
Handling non-canceled request textDocument/codeAction (150)
Skipping request - language services disabled
Handling non-canceled request textDocument/documentSymbol (151)
Handling non-canceled request textDocument/semanticTokens/full (152)
Skipping request - language services disabled
Handling non-canceled request textDocument/inlayHint (153)
Skipping request - language services disabled
Handling non-canceled request textDocument/documentHighlight (154)
Skipping request - language services disabled
Prepare to check 2167 files.
Populated all files in the project path.
Handling non-canceled request textDocument/documentSymbol (155)
Handling non-canceled request textDocument/codeAction (156)
Skipping request - language services disabled
Handling non-canceled request textDocument/hover (157)
Skipping request - language services disabled
Handling non-canceled request textDocument/hover (158)
Skipping request - language services disabled
Handling non-canceled request textDocument/hover (159)
Skipping request - language services disabled
Handling non-canceled request textDocument/hover (160)
Skipping request - language services disabled
Handling non-canceled request textDocument/codeAction (161)
Skipping request - language services disabled
Handling non-canceled request textDocument/hover (162)
Skipping request - language services disabled
Handling non-canceled request textDocument/documentHighlight (163)
Skipping request - language services disabled
Handling non-canceled request textDocument/codeAction (164)
Skipping request - language services disabled
Handling non-canceled request textDocument/codeAction (165)
Skipping request - language services disabled
Handling non-canceled request textDocument/codeAction (166)
Skipping request - language services disabled
Handling non-canceled request textDocument/inlayHint (167)
Skipping request - language services disabled
Request textDocument/inlayHint (168) is canceled due to subsequent mutation
Handling non-canceled request textDocument/semanticTokens/full (169)
Skipping request - language services disabled
Handling non-canceled request textDocument/documentSymbol (170)
Handling non-canceled request textDocument/documentSymbol (171)
Handling non-canceled request textDocument/inlayHint (172)
Skipping request - language services disabled
Handling non-canceled request textDocument/codeAction (173)
Skipping request - language services disabled
Handling non-canceled request textDocument/inlayHint (174)
Skipping request - language services disabled
Handling non-canceled request textDocument/codeAction (175)
Skipping request - language services disabled
Handling non-canceled request textDocument/hover (176)
Skipping request - language services disabled
Handling non-canceled request pyrefly/textDocument/typeErrorDisplayStatus (177)
Handling non-canceled request textDocument/codeAction (178)
Skipping request - language services disabled
Handling non-canceled request textDocument/inlayHint (179)
Skipping request - language services disabled
Handling non-canceled request textDocument/documentHighlight (180)
Skipping request - language services disabled
Handling non-canceled request textDocument/codeAction (181)
Skipping request - language services disabled
Handling non-canceled request textDocument/semanticTokens/full (182)
Skipping request - language services disabled
Handling non-canceled request textDocument/documentSymbol (183)
Handling non-canceled request pyrefly/textDocument/typeErrorDisplayStatus (184)
Handling non-canceled request textDocument/codeAction (185)
Skipping request - language services disabled
Handling non-canceled request textDocument/documentSymbol (186)
Handling non-canceled request textDocument/semanticTokens/full (187)
Skipping request - language services disabled
Handling non-canceled request textDocument/inlayHint (188)
Skipping request - language services disabled
Handling non-canceled request textDocument/documentSymbol (189)
Handling non-canceled request textDocument/codeAction (190)
Skipping request - language services disabled
Handling non-canceled request textDocument/documentHighlight (191)
Skipping request - language services disabled
Handling non-canceled request textDocument/codeAction (192)
Skipping request - language services disabled
Handling non-canceled request textDocument/hover (193)
Skipping request - language services disabled
Handling non-canceled request textDocument/codeAction (194)
Skipping request - language services disabled
Handling non-canceled request textDocument/codeAction (195)
Skipping request - language services disabled
Request textDocument/inlayHint (196) is canceled due to subsequent mutation
Handling non-canceled request textDocument/semanticTokens/full (197)
Skipping request - language services disabled
Handling non-canceled request textDocument/documentSymbol (198)
Handling non-canceled request textDocument/documentSymbol (199)
Handling non-canceled request textDocument/codeAction (200)
Skipping request - language services disabled
Handling non-canceled request textDocument/inlayHint (201)
Skipping request - language services disabled
Handling non-canceled request textDocument/codeAction (202)
Skipping request - language services disabled
Handling non-canceled request textDocument/inlayHint (203)
Skipping request - language services disabled
Handling non-canceled request textDocument/codeAction (204)
Skipping request - language services disabled
ERROR Thread panicked, shutting down: panicked at pyrefly/lib/state/state.rs:1633:17:
assertion failed: inserted
Backtrace:
   0: std::sync::poison::once::Once::call_once::{{closure}}
   1: std::sys::sync::once::futex::Once::call
   2: pyrefly_util::panic::print_panic
   3: pyrefly_util::panic::exit_on_panic::{{closure}}
   4: std::panicking::rust_panic_with_hook
   5: std::panicking::begin_panic_handler::{{closure}}
   6: std::sys::backtrace::__rust_end_short_backtrace
   7: __rustc::rust_begin_unwind
   8: core::panicking::panic_fmt
   9: core::panicking::panic
  10: pyrefly::state::state::TransactionHandle::get_module
  11: <pyrefly::state::state::TransactionHandle as pyrefly::export::exports::LookupExport>::get
  12: pyrefly::binding::stmt::<impl pyrefly::binding::bindings::BindingsBuilder>::stmt
  13: pyrefly::state::steps::Step::step_answers
  14: core::ops::function::FnOnce::call_once{{vtable.shim}}
  15: pyrefly::state::state::Transaction::demand
  16: pyrefly::state::state::Transaction::run_step::{{closure}}
  17: <rayon_core::job::HeapJob<BODY> as rayon_core::job::Job>::execute
  18: rayon_core::registry::WorkerThread::wait_until_cold
  19: std::sys::backtrace::__rust_begin_short_backtrace
  20: core::ops::function::FnOnce::call_once{{vtable.shim}}
  21: std::sys::pal::unix::thread::Thread::new::thread_start
PANIC Sorry, Pyrefly crashed, this is always a bug in Pyrefly itself.
PANIC Please report the bug at https://github.com/facebook/pyrefly/issues/new

The logs show a series of requests being handled by the LSP server. Many of them are skipped because language services are disabled, which aligns with my settings. The logs trace the operations up to the point of the crash. I noticed that many requests like textDocument/documentSymbol, textDocument/codeAction, and textDocument/inlayHint were being handled. The key here is the specific sequence of events leading up to the crash.

Next Steps: Reporting the Issue and Possible Workarounds

I've reported this bug to the Pyrefly developers at the link provided in the error message, including the details above. If you've run into a similar issue or have any insights, please comment below. For now, I would suggest the following steps:

  1. Report the Bug: If you encounter this issue, make sure to report it to the Pyrefly developers with all relevant information. The more details you provide, the easier it will be for them to fix the issue.
  2. Check for Updates: Keep an eye out for updates to the Pyrefly extension. The developers may release a fix in a future version.
  3. Alternative Approaches: If you urgently need to perform find and replace operations, consider using other tools or methods within VS Code. You can try the built-in find and replace or explore other extensions that offer similar functionalities. Also, consider the option of disabling the bulk changes.

I'll keep you posted on any updates or solutions I find. Thanks for reading, and let's hope this gets resolved soon! This issue is probably a bug in the extension itself, and by providing detailed information, we can contribute to making Pyrefly more stable for everyone.