Skip to content
Latchkey

Node "ENOENT open .env" Missing Env File at Runtime in CI - Fix It

A .env file is local-only and is not committed, so loading it at runtime in CI throws ENOENT. Real CI secrets come from the workflow environment, not a file.

What this error means

A node process or dotenv load throws Error: ENOENT: no such file or directory, open '.env' in CI, because the env file exists only on developer machines.

node
Error: ENOENT: no such file or directory, open '/home/runner/work/app/app/.env'
    at Object.openSync (node:fs:603:3)
    at Object.readFileSync (node:fs:471:35)
    at Object.config (node_modules/dotenv/lib/main.js:84:35)

Common causes

The .env file is gitignored

The env file is not committed (correctly, since it holds secrets), so it is absent on a clean CI checkout.

Hard requiring the file instead of falling back to process.env

Code calls dotenv in a way that throws when the file is missing rather than reading from the real environment.

How to fix it

Provide variables via workflow env

  1. Set the required variables in the workflow env or from secrets.
  2. Let the code read process.env directly in CI.
GitHub Actions
- run: node server.js
  env:
    DATABASE_URL: ${{ secrets.DATABASE_URL }}

Make dotenv loading optional

  1. Load .env only if present and fall back to process.env otherwise.
JavaScript
import { existsSync } from 'node:fs';
if (existsSync('.env')) (await import('dotenv')).config();

How to prevent it

  • Treat process.env as the source of truth, load .env only as an optional local convenience, and supply CI variables through workflow env or secrets.

Related guides

Tired of flaky CI? Latchkey auto-heals failed jobs and retries them for you. Start free →