Language Server Panic Crash on Startup in Remote Container in VSCode
Describe the Bug
When I use VSCode to connect to a remote dev Container, pyrefly loads up and then almost immediately crashes.
This is the case for around 80% of the startups. I currently "fix" it by restarting until the Language Server does not crash, which then leads to a stable environment.
This is the startup configuration: ( blanked project information )
The codebase is not public, so i cant share anything apart from some traces from the extension log:
ERROR Thread panicked, shutting down: panicked at pyrefly/lib/state/state.rs:1559: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::lookup_answer 17: pyrefly::alt::answers_solver::AnswersSolver<Ans>::get_from_module 18: pyrefly::alt::attr::<impl pyrefly::alt::answers_solver::AnswersSolver<Ans>>::lookup_attr_from_attribute_base1 19: pyrefly::alt::attr::<impl pyrefly::alt::answers_solver::AnswersSolver<Ans>>::lookup_attr_from_attribute_base 20: pyrefly::alt::attr::<impl pyrefly::alt::answers_solver::AnswersSolver<Ans>>::type_of_attr_get 21: pyrefly::alt::expr::<impl pyrefly::alt::answers_solver::AnswersSolver<Ans>>::attr_infer 22: pyrefly::alt::expr::<impl pyrefly::alt::answers_solver::AnswersSolver<Ans>>::expr_infer_type_info_with_hint 23: pyrefly::alt::expr::<impl pyrefly::alt::answers_solver::AnswersSolver<Ans>>::expr_infer_type_no_trace 24: pyrefly::alt::expr::<impl pyrefly::alt::answers_solver::AnswersSolver<Ans>>::expr_infer_type_info_with_hint 25: pyrefly::alt::expr::<impl pyrefly::alt::answers_solver::AnswersSolver<Ans>>::expr 26: pyrefly::alt::solve::<impl pyrefly::alt::answers_solver::AnswersSolver<Ans>>::binding_to_type 27: pyrefly::alt::solve::<impl pyrefly::alt::answers_solver::AnswersSolver<Ans>>::binding_to_type_info 28: pyrefly::alt::solve::<impl pyrefly::alt::answers_solver::AnswersSolver<Ans>>::solve_binding 29: pyrefly::alt::answers_solver::AnswersSolver<Ans>::calculate_and_record_answer 30: pyrefly::alt::answers_solver::AnswersSolver<Ans>::get_idx 31: pyrefly::alt::solve::<impl pyrefly::alt::answers_solver::AnswersSolver<Ans>>::binding_to_type 32: pyrefly::alt::solve::<impl pyrefly::alt::answers_solver::AnswersSolver<Ans>>::binding_to_type_info 33: pyrefly::alt::solve::<impl pyrefly::alt::answers_solver::AnswersSolver<Ans>>::solve_binding 34: pyrefly::alt::answers_solver::AnswersSolver<Ans>::calculate_and_record_answer 35: pyrefly::alt::answers_solver::AnswersSolver<Ans>::get_idx 36: pyrefly::alt::solve::<impl pyrefly::alt::answers_solver::AnswersSolver<Ans>>::binding_to_type_info 37: pyrefly::alt::solve::<impl pyrefly::alt::answers_solver::AnswersSolver<Ans>>::solve_binding 38: pyrefly::alt::answers_solver::AnswersSolver<Ans>::calculate_and_record_answer 39: pyrefly::alt::answers_solver::AnswersSolver<Ans>::get_idx 40: pyrefly::alt::solve::<impl pyrefly::alt::answers_solver::AnswersSolver<Ans>>::binding_to_type_info 41: pyrefly::alt::solve::<impl pyrefly::alt::answers_solver::AnswersSolver<Ans>>::solve_binding 42: pyrefly::alt::answers_solver::AnswersSolver<Ans>::calculate_and_record_answer 43: pyrefly::alt::answers_solver::AnswersSolver<Ans>::get_idx 44: pyrefly::alt::answers_solver::AnswersSolver<Ans>::calculate_and_record_answer 45: pyrefly::alt::answers_solver::AnswersSolver<Ans>::get_idx 46: pyrefly::alt::expr::<impl pyrefly::alt::answers_solver::AnswersSolver<Ans>>::expr_infer_type_info_with_hint 47: pyrefly::alt::expr::<impl pyrefly::alt::answers_solver::AnswersSolver<Ans>>::expr 48: pyrefly::alt::solve::<impl pyrefly::alt::answers_solver::AnswersSolver<Ans>>::binding_to_type 49: pyrefly::alt::solve::<impl pyrefly::alt::answers_solver::AnswersSolver<Ans>>::binding_to_type_info 50: pyrefly::alt::solve::<impl pyrefly::alt::answers_solver::AnswersSolver<Ans>>::solve_binding 51: pyrefly::alt::answers_solver::AnswersSolver<Ans>::calculate_and_record_answer 52: pyrefly::alt::answers_solver::AnswersSolver<Ans>::get_idx 53: <alloc::vec::Vec<T> as alloc::vec::spec_from_iter_nested::SpecFromIterNested<T,I>>::from_iter 54: pyrefly::alt::solve::<impl pyrefly::alt::answers_solver::AnswersSolver<Ans>>::binding_to_type 55: pyrefly::alt::solve::<impl pyrefly::alt::answers_solver::AnswersSolver<Ans>>::binding_to_type_info 56: pyrefly::alt::solve::<impl pyrefly::alt::answers_solver::AnswersSolver<Ans>>::solve_binding 57: pyrefly::alt::answers_solver::AnswersSolver<Ans>::calculate_and_record_answer 58: pyrefly::alt::answers_solver::AnswersSolver<Ans>::get_idx 59: pyrefly::alt::answers_solver::AnswersSolver<Ans>::calculate_and_record_answer 60: pyrefly::alt::answers_solver::AnswersSolver<Ans>::get_idx 61: pyrefly::alt::solve::<impl pyrefly::alt::answers_solver::AnswersSolver<Ans>>::binding_to_type 62: pyrefly::alt::solve::<impl pyrefly::alt::answers_solver::AnswersSolver<Ans>>::binding_to_type_info 63: pyrefly::alt::solve::<impl pyrefly::alt::answers_solver::AnswersSolver<Ans>>::solve_binding 64: pyrefly::alt::answers_solver::AnswersSolver<Ans>::calculate_and_record_answer 65: pyrefly::alt::answers_solver::AnswersSolver<Ans>::get_idx 66: pyrefly::alt::class::class_field::<impl pyrefly::alt::answers_solver::AnswersSolver<Ans>>::analyze_class_field_value 67: pyrefly::alt::answers_solver::AnswersSolver<Ans>::calculate_and_record_answer 68: pyrefly::alt::answers_solver::AnswersSolver<Ans>::get_idx 69: pyrefly::alt::answers_solver::AnswersSolver<Ans>::get_from_module 70: pyrefly::alt::class::class_field::<impl pyrefly::alt::answers_solver::AnswersSolver<Ans>>::get_non_synthesized_field_from_current_class_only 71: pyrefly::alt::class::class_field::<impl pyrefly::alt::answers_solver::AnswersSolver<Ans>>::get_class_member 72: pyrefly::alt::class::class_field::<impl pyrefly::alt::answers_solver::AnswersSolver<Ans>>::instance_as_dunder_call 73: pyrefly::alt::call::<impl pyrefly::alt::answers_solver::AnswersSolver<Ans>>::as_call_target_impl 74: pyrefly::alt::call::<impl pyrefly::alt::answers_solver::AnswersSolver<Ans>>::as_call_target_or_error 75: pyrefly::alt::answers_solver::AnswersSolver<Ans>::calculate_and_record_answer 76: pyrefly::alt::answers_solver::AnswersSolver<Ans>::get_idx 77: pyrefly::alt::solve::<impl pyrefly::alt::answers_solver::AnswersSolver<Ans>>::binding_to_type 78: pyrefly::alt::solve::<impl pyrefly::alt::answers_solver::AnswersSolver<Ans>>::binding_to_type_info 79: pyrefly::alt::solve::<impl pyrefly::alt::answers_solver::AnswersSolver<Ans>>::solve_binding 80: pyrefly::alt::answers_solver::AnswersSolver<Ans>::calculate_and_record_answer 81: pyrefly::alt::answers_solver::AnswersSolver<Ans>::get_idx 82: pyrefly::alt::answers::Answers::solve 83: pyrefly::state::steps::Step::step_solutions 84: core::ops::function::FnOnce::call_once{{vtable.shim}} 85: pyrefly::state::state::Transaction::demand 86: pyrefly::state::state::Transaction::run_step::{{closure}} 87: <rayon_core::job::HeapJob<BODY> as rayon_core::job::Job>::execute 88: rayon_core::registry::WorkerThread::wait_until_cold 89: rayon_core::scope::scope::{{closure}} 90: <rayon_core::job::StackJob<L,F,R> as rayon_core::job::Job>::execute 91: rayon_core::registry::WorkerThread::wait_until_cold 92: std::sys::backtrace::__rust_begin_short_backtrace 93: core::ops::function::FnOnce::call_once{{vtable.shim}} 94: std::sys::pal::unix::thread::Thread::new::thread_start`
The logs then show some more responses and end in:
[Error - 8:24:31 AM] Client Pyrefly language server: connection to server is erroring. write EPIPE Shutting down server. [Trace - 8:24:31 AM] Sending request 'shutdown - (17)'. [Error - 8:24:31 AM] Client Pyrefly language server: connection to server is erroring. write EPIPE [Error - 8:24:31 AM] Connection to server got closed. Server will not be restarted. [Error - 8:24:31 AM] Server process exited with code 101. [Error - 8:24:31 AM] Stopping server failed Message: Cannot call write after a stream was destroyed Code: -32099 [Error - 8:24:31 AM] Stopping server failed Message: Cannot call write after a stream was destroyed Code: -32099
Sandbox Link
No response
(Only applicable for extension issues) IDE Information
VSCode version 1.106.2, Extension version 0.43.1
Workspace spanning 2 repositories,
From a bit of poking, the crash appears to be in the get_module rdeps insertion check:
fn get_module(
&self,
module: ModuleName,
path: Option<&ModulePath>,
) -> FindingOrError<ArcId<ModuleDataMut>> {
let require = self.module_data.state.read().require;
if let Some(res) = self.module_data.deps.read().get(&module).map(|x| x.first())
&& path.is_none_or(|path| path == res.path())
{
return FindingOrError::new_finding(self.transaction.get_imported_module(res, require));
}
let handle = self
.transaction
.import_handle(&self.module_data.handle, module, path);
handle.map(|handle| {
let res = self.transaction.get_imported_module(&handle, require);
let mut write = self.module_data.deps.write();
let did_insert = match write.entry(module) {
Entry::Vacant(e) => {
e.insert(SmallSet1::new(handle));
true
}
Entry::Occupied(mut e) => e.get_mut().insert(handle),
};
if did_insert {
let inserted = res.rdeps.lock().insert(self.module_data.handle.dupe());
assert!(inserted); /* <------- panic seems to be coming from here */
}
// Make sure we hold the deps write lock until after we insert into rdeps.
drop(write);
res
})
}
See also https://github.com/facebook/pyrefly/issues/1424
I have been investigating a bug that crashes at the same place, and have a change up for review internally to fix it. Would appreciate if you could try out the fix when it's ready. Will keep you posted.
This issue has someone assigned, but has not had recent activity for more than 2 weeks.
If you are still working on this issue, please add a comment so everyone knows. Otherwise, please unassign yourself and allow someone else to take over.
Thank you for your contributions!