You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Node.js报错ENOTDIR:scandir非目录问题的排查与修复方案

Discord机器人ENOTDIR错误原因及修复方案

问题详情

开发Discord机器人Logs功能时出现异常,移除bot.js中相关代码后仍报错,错误信息如下:

node:internal/fs/utils:351
    throw err;
    ^

Error: ENOTDIR: not a directory, scandir './src/functions/.DS_Store'
    at Object.readdirSync (node:fs:1532:3)
    at Object.<anonymous> (/Users/roopa/Desktop/projects/LLbot/src/bot.js:43:6)
    at Module._compile (node:internal/modules/cjs/loader:1255:14)
    at Module._extensions..js (node:internal/modules/cjs/loader:1309:10)
    at Module.load (node:internal/modules/cjs/loader:1113:32)
    at Module._load (node:internal/modules/cjs/loader:960:12)
    at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:83:12)
    at node:internal/main/run_main_module:23:47 {
  errno: -20,
  syscall: 'scandir',
  code: 'ENOTDIR',
  path: './src/functions/.DS_Store'
}

引发错误的代码片段:

const functionFolders = fs.readdirSync(`./src/functions`);
for (const folder of functionFolders) {
  const functionFiles = fs
    .readdirSync(`./src/functions/${folder}`)
    .filter((file) => file.endsWith(".js"));
  for (const file of functionFiles) require(`./functions/${folder}/${file}`);
}

错误原因

ENOTDIR错误意味着代码试图对非目录文件执行目录操作,具体原因:

  • fs.readdirSync('./src/functions')会读取该目录下所有内容,包括Mac系统自动生成的隐藏文件.DS_Store(这是文件,不是目录)
  • 循环中直接把每个读取到的项当作目录处理,调用fs.readdirSync('./src/functions/.DS_Store')时,因目标是文件而非目录,触发报错。

修复方案

方案1:通用过滤(推荐)

在处理前判断每个项是否为目录,只对目录执行后续操作:

const fs = require('fs');
const path = require('path');

const functionsDir = './src/functions';
const functionFolders = fs.readdirSync(functionsDir);

for (const folder of functionFolders) {
  const folderPath = path.join(functionsDir, folder);
  // 跳过非目录项
  if (!fs.statSync(folderPath).isDirectory()) continue;
  
  const functionFiles = fs
    .readdirSync(folderPath)
    .filter((file) => file.endsWith(".js"));
  for (const file of functionFiles) require(`./functions/${folder}/${file}`);
}

方案2:针对性过滤.DS_Store

如果仅需解决Mac系统的这个特定文件问题,可直接在读取结果中过滤掉.DS_Store:

const functionFolders = fs.readdirSync(`./src/functions`).filter(item => item !== '.DS_Store');
for (const folder of functionFolders) {
  const functionFiles = fs
    .readdirSync(`./src/functions/${folder}`)
    .filter((file) => file.endsWith(".js"));
  for (const file of functionFiles) require(`./functions/${folder}/${file}`);
}

额外建议

  • 将.DS_Store添加到项目的.gitignore文件中,避免提交到版本库
  • 方案1能适配所有非目录干扰项,通用性更强,优先选择

内容的提问来源于stack exchange,提问作者Joe Mama

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 12:37:18