#Как проявляется неисправность
Node.js не может найти относительный путь к файлу после запуска из cron, systemd, редактора или другого каталога. Часто файл существует, но process.cwd() отличается от директории исходного файла.
#Причины и отличительные признаки
| Возможная причина | Как узнать | Что делать |
|---|---|---|
| Текущий каталог процесса изменилсяОтносительный путь в fs вычисляется от process.cwd(). | Ошибка ENOENT с ./config.json только в службе | Использовать устойчивый путь от модуля или рабочий каталог. |
| Файлу нет доступа у пользователя службыВыполняемый пользователь отличается от разработчика. | Ошибка EACCES, но файл существует | Проверить точные права на нужный файл. |
| Регистр или символическая ссылка не совпадаютФайловая система Linux обычно различает регистр имён. | Локально Windows работает, на Linux — нет | Сверить имя и расположение. |
#Пошаговая диагностика и исправление
- Запишите точную ошибку и искомый путьИз журнала сохраните код
ENOENTлибоEACCESи значениеpathдля вызоваfs.readFile,fs.openили чтения конфигурации. ОшибкаENOENTозначает, что путь не найден в текущем контексте, аEACCES— отказ в доступе; способы исправления различаются.
- Покажите рабочий каталог и исполняемый NodeВ тестовой копии временно добавьте безопасный вывод
console.log(process.cwd(), process.execPath)без содержимого секретных файлов. Повторите запуск из терминала и службы, сравните результаты. Если копия пишет путь/, а файл лежит в/srv/myapp, относительный путь будет разрешён не там.
- Проверьте существование файла именно там, где его ищутВ терминале процесса или под тем же пользователем откройте путь файловым менеджером/
ls -l. Например,ls -l /srv/myapp/config/settings.json; если пути нет, уточните дерево проекта. Не создавайте пустой конфигурационный файл лишь для подавления ошибки. - Linux: укажите реальный путь из ошибки, приведённый пример условныйLinux · Терминал (Bash)КомандаLinux: укажите реальный путь из ошибки, приведённый пример условный. Команда проверяет наличие файла и права, ничего не изменяет. Windows PowerShell:
Get-Item "C:\путь\к\проекту\config\settings.json".ls -l /srv/myapp/config/settings.json
- Стройте путь относительно модуля для CommonJSЕсли приложение написано в CommonJS, используйте
path.join(__dirname, "config", "settings.json")рядом с кодом чтения файла. Здесь__dirname— каталог выполняемого модуля; такой путь не меняется при запуске из другой рабочей папки. Проверяйте, что целевой файл действительно находится рядом.
- Для ESM используйте корректный URL модуляВ модулях ECMAScript, где
__dirnameотсутствует, можно создать путь черезfileURLToPath(new URL("./config/settings.json", import.meta.url))при соответствующей структуре. Не используйте фиктивную глобальную переменную__dirnameв ESM. - Дополнительная команда по темеLinux · Терминал (Bash)КомандаКоманда диагностики текущего терминала, не обязательно совпадающего со службой; значение службы уточняйте в её процессе.
node -e "console.log(process.cwd()); console.log(process.execPath)"
- Если нужен фиксированный каталог для всей службыПроверьте
WorkingDirectory=/srv/myappв unit systemd или настройку рабочего каталога задания. Изменения службы делайте с администратором после резервной копии конфигурации; не копируйте файлы в корень/, чтобы относительный путь случайно заработал.
- Испытайте на повторном запускеЗапустите программу из произвольной другой папки и затем через реальный механизм запуска. При успешном чтении файл должен находиться без ENOENT, а права сохранять минимально необходимый уровень. Если остаётся EACCES, проверьте конкретного пользователя, группу и разрешение на чтение только нужного файла.
#Проверка результата
Файл читается при запуске из терминала и службы, а путь не зависит от случайной текущей директории процесса.
При повторной ошибке сравните фактическую команду запуска, журнал приложения и параметры окружения. Если изменения затронули службу, верните предыдущую конфигурацию из сохранённой копии и разберите исходное сообщение об ошибке.