{"record":{"id":"3f4405b2d492c8c6","repo":"denoland/deno","slug":"err-dir-closed","errorCode":"ERR_DIR_CLOSED","errorMessage":"Directory handle was closed","messagePattern":"Directory handle was closed","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"ext/node/polyfills/_fs/_fs_dir.ts","lineNumber":96,"sourceCode":"              iteratorResult.done\n                ? null\n                : direntFromDeno(iteratorResult.value, this.#dirPath),\n            );\n          }\n        },\n        (err) => {\n          if (callback) {\n            callback(err);\n          }\n          reject(err);\n        },\n      );\n    });\n  }\n\n  readSync(): Dirent | null {\n    if (this.#closed) {\n      throw new ERR_DIR_CLOSED();\n    }\n    if (!this.#syncIterator) {\n      this.#syncIterator = Deno.readDirSync(this.path)![SymbolIterator]();\n    }\n\n    const iteratorResult = ArrayIteratorPrototypeNext(this.#syncIterator);\n    if (iteratorResult.done) {\n      return null;\n    } else {\n      return direntFromDeno(iteratorResult.value, this.#dirPath);\n    }\n  }\n\n  /**\n   * Unlike Node, Deno does not require managing resource ids for reading\n   * directories, and therefore does not need to close directories when\n   * finished reading.\n   */","sourceCodeStart":78,"sourceCodeEnd":114,"githubUrl":"https://github.com/denoland/deno/blob/9ad36f7a2cce60488e6ec52283efb32efddaf93a/ext/node/polyfills/_fs/_fs_dir.ts#L78-L114","documentation":"ERR_DIR_CLOSED ('Directory handle was closed') is thrown by Dir.readSync() and the async read path after close()/closeSync() has been called on the handle. The class tracks a #closed flag; any read attempt afterwards fails before touching the filesystem. The error carries code ERR_DIR_CLOSED, matching Node.","triggerScenarios":"const d = fs.opendirSync(dir); d.closeSync(); d.readSync(); a cleanup/error path closing a shared handle while another loop still reads it; double iteration where the first consumer closes the handle.","commonSituations":"Helper functions that close handles on error while their caller continues iterating; early-break loops followed by a finally that reads once more; refactors that move close() earlier in the lifecycle.","solutions":["Set the handle reference to null after closing and check it before every read","Pair opendir with exactly one consumer - the scope that reads is the scope that closes","For early exit use break and let the owning scope perform close()"],"exampleFix":"// before\nconst dir = fs.opendirSync(path);\nfor (;;) {\n  const ent = dir.readSync();\n  if (!ent) break;\n  if (ent.name === 'stop') dir.closeSync(); // then loop calls readSync again\n}\n\n// after\nconst dir = fs.opendirSync(path);\nlet closed = false;\ntry {\n  for (;;) {\n    const ent = dir.readSync();\n    if (!ent) break;\n    if (ent.name === 'stop') break;\n  }\n} finally {\n  if (!closed) { dir.closeSync(); closed = true; }\n}","handlingStrategy":"validation","validationCode":"class SafeDir {\n  #dir: fs.Dir<string>;\n  #closed = false;\n  constructor(path: string) { this.#dir = fs.opendirSync(path); }\n  readSync() {\n    if (this.#closed) throw new Error('dir already closed');\n    return this.#dir.readSync();\n  }\n  closeSync() {\n    if (!this.#closed) { this.#dir.closeSync(); this.#closed = true; }\n  }\n}","typeGuard":null,"tryCatchPattern":"try {\n  const entry = dir.readSync();\n} catch (e) {\n  if ((e as NodeJS.ErrnoException).code === 'ERR_DIR_CLOSED') {\n    break; // iteration finished by another path - stop cleanly\n  }\n  throw e;\n}","preventionTips":["Close directory handles exactly once, in the same scope that iterates them","Use break for early exit and let the owning scope close the handle","Check a closed flag before every read when handles are shared across helper functions"],"tags":["deno","node-compat","fs","opendir","resource-lifecycle"],"backgroundTag":"use-after-close","analyzedSha":"9ad36f7a2cce60488e6ec52283efb32efddaf93a","analyzedAt":"2026-08-20T13:07:44.778Z","contentChangedAt":"2026-08-20T13:07:44.778Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}