gleam-lang/gleam · critical
could not lock beam_compiler
Error message
could not lock beam_compiler
What it means
`ProjectIO` stores the persistent BEAM compiler handle in a `std::sync::Mutex<Option<BeamCompilerInstance>>` (imported at compiler-cli/src/fs.rs:23). `initialise_beam_compiler` (fs.rs:111) locks it, and `Mutex::lock()` only fails when the mutex is POISONED — some other thread panicked while holding the lock, typically the `panic!("BEAM compiler instance exited: ...")` from beam_compiler.rs:45. The `.expect("could not lock beam_compiler")` therefore aborts as a follow-on symptom of an earlier panic in the same process.
Source
Thrown at compiler-cli/src/fs.rs:111
beam_compiler: Arc<Mutex<Option<BeamCompilerInstance>>>,
}
impl ProjectIO {
pub fn new() -> Self {
Self {
beam_compiler: Arc::new(Mutex::new(None)),
}
}
pub fn boxed() -> Box<Self> {
Box::new(Self::new())
}
pub(crate) fn initialise_beam_compiler(&self) -> Result<(), Error> {
let mut guard = self
.beam_compiler
.lock()
.expect("could not lock beam_compiler");
if guard.is_none() {
*guard = Some(BeamCompilerInstance::new(self)?);
}
Ok(())
}
}
impl FileSystemReader for ProjectIO {
fn read(&self, path: &Utf8Path) -> Result<String, Error> {
read(path)
}
fn read_bytes(&self, path: &Utf8Path) -> Result<Vec<u8>, Error> {
read_bytes(path)
}
fn is_file(&self, path: &Utf8Path) -> bool {
path.is_file()View on GitHub (pinned to 7e623aa83d)
Solutions
- Restart the process: re-run the CLI command, or restart the Gleam LSP/editor — poisoning lasts only for the process lifetime
- Find and fix the ORIGINAL panic in the logs above this one (usually 'BEAM compiler instance exited: ...'): verify Erlang health and check for OOM kills
- Re-run the build after the environment is fixed; the new process re-creates the BEAM instance cleanly
- Report repeatable poisoning chains at https://github.com/gleam-lang/gleam/issues with both panic messages
Defensive patterns
Strategy: retry
Prevention
- Treat 'could not lock beam_compiler' as a symptom: search the log upward for the first panic (usually the BEAM instance exiting) and fix that
- Restart the Gleam LSP after Erlang changes or any visible BEAM crash
- Keep Erlang healthy and memory headroom available so the original panic never fires
When it happens
Trigger: Any earlier panic while this lock is held: the BEAM helper process dying mid-compile, or a panic while constructing `BeamCompilerInstance`. Afterwards every `initialise_beam_compiler` call in the same process panics too — mostly visible in the long-lived Gleam language server, where one poisoned lock breaks all later compiles until restart.
Common situations: Gleam LSP in an editor that stays open across an Erlang outage/upgrade; a build session whose escript helper was OOM-killed followed by another compile in the same process; flaky sandboxed environments killing the BEAM child.
Related errors
- BEAM compiler instance exited: {status}
- Non Utf-8 Path
- `panic` expression evaluated.
- Unable to start Tokio async runtime
- Unable to start Tokio async runtime
AI-assisted analysis of gleam-lang/gleam@7e623aa83d (2026-08-17).
Data as JSON: /api/errors/86f7203b5a95ec8c.
Report an issue: GitHub.