Hacktoberfest 2026: le issue che i maintainer hanno segnato per ottobre, aperte e adatte ai principianti. Sfoglia le issue Hacktoberfest

`FileSystem.Lock.aquire` ends in `UnexpectedError ENOENT` when the lock is released while it checks it

Aperta Adatta ai principianti
#14 0 commenti 0 reazioni 0 assegnatari Vedi su GitHub

Nessuno ha ancora preso questa issue.

Valutazione

Difficoltà
2/5
Tempo stimato
1-3 ore
Idoneità per principianti
78/100
Tipo di issue
Bug
Chiarezza
Specificata chiaramente
Stato di attività
Attiva
Stack tecnologico
javascript, node.js

Direzione di ricerca

Inizia individuando l’handler LockMetaCheck e i predicati di errore di FileSystem nel codice sorgente di compiler-node. Esegui la riproduzione collegata o i comandi gren make/node mentre churn.js rimuove ripetutamente .lock. Il lavoro è completato quando un lock che scompare brevemente viene ritentato e l’esecuzione non segnala più UnexpectedError ENOENT, terminando solo con gli esiti lock acquired o already locked.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Descrizione

Found against: gren 0.6.6, gren-lang/compiler-node 5.0.0, gren-lang/core 7.4.2, gren-lang/node 6.1.3, node 22
Reproduction: https://github.com/gilramir/gren-bug-reports/tree/main/2026-09-16-lock-vanishes-during-metadata

Taking a lock that another process holds only briefly often ends in
UnexpectedError, when it should end with the lock taken or AlreadyLocked.
aquire creates the lock directory; if it exists, it reads its metadata to see
whether the lock is stale. If the other process removes the lock in between,
metadata fails with ENOENT, and the handler that means to retry tests for
the wrong error.

Reproduction

gren.json: a node application with "gren-lang/compiler-node": "5.0.0", "gren-lang/core": "7.4.2", "gren-lang/node": "6.1.3" (indirect "gren-lang/compiler-common": "3.0.0", "gren-lang/url": "6.0.0").

churn.js stands in for another process that holds the lock very briefly:

// Create and remove ./.lock in a tight loop, as another process holding the
// lock very briefly would.
const fs = require("node:fs");
for (;;) {
  try { fs.mkdirSync(".lock"); } catch (e) {}
  try { fs.rmdirSync(".lock"); } catch (e) {}
}

src/Main.gren tries to take the lock 2000 times, without retries, releasing it
whenever it gets it, and counts how each attempt ended:

(source elided here as it's very long)

gren make Main --output=app
node churn.js &
node app

Output (counts vary with timing):

outcome                      count
UnexpectedError ENOENT         953
already locked                 156
lock acquired                  891

Cause

LockMetaCheck { path, attempt, result = Err fsErr } ->
    if FileSystem.errorIsFileExists fsErr then
        -- Lock might have been removed while we asked for metadata
        update fsPerm (Lock { path = fromLockPath path, attempt = attempt + 1 }) model

    else
        UnexpectedError { path = fromLockPath path, error = fsErr }

The comment describes the right recovery, but reading a directory's metadata
never fails with EEXIST, so a lock that has been removed takes the else
branch.

Proposed Fix

The check should be FileSystem.errorIsNoSuchFileOrDirectory

With it, the same program gave 325 already locked and 1675 lock acquired.

Lingua principale
JavaScript
Stelle
2
Fork
3
Metriche di merge delle PR
Nessuna PR unita negli ultimi 30g

Preparare l'ambiente

Non abbiamo ancora controllato i file di configurazione di questo progetto. Parti dal suo README e consulta la nostra guida al primo contributo per i passaggi generali.

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di gren-lang/compiler-node

Tutte le issue di gren-lang/compiler-node

Issue simili

Altre issue su JavaScript

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.