affaan-m/ECC · error

--config-dir must be an existing absolute directory.

Error message

--config-dir must be an existing absolute directory.

What it means

Thrown by validateNodeQualificationArgs in scripts/ito.js:124 when the --config-dir value passed to `ecc ito evals` fails path.isAbsolute(). The Itô evals path is a live sixtytwo node-qualification workflow that needs an operator-owned config directory, so relative paths are rejected outright before any filesystem access is attempted. The absolute-path gate is the first of several layered checks on --config-dir (existence, directory-ness, presence of sixtytwo.yaml).

Source

Thrown at scripts/ito.js:124

function validateNodeQualificationArgs(args, environment) {
  if (environment.ITO_ENABLE_SIXTYTWO_LIVE !== "1") {
    throw new Error(
      "Live node qualification requires ITO_ENABLE_SIXTYTWO_LIVE=1 before any process is started."
    );
  }
  if (args.filter((value) => value === "--live-sixtytwo").length !== 1) {
    throw new Error(
      "Live node qualification requires --live-sixtytwo exactly once before any process is started."
    );
  }
  requiredOptionValue(args, "--cluster");
  const nodes = requiredOptionValue(args, "--nodes");
  if (!nodes.split(",").every((node) => node.trim().length > 0)) {
    throw new Error("--nodes must explicitly list one or more non-empty nodes.");
  }
  const configDirectory = requiredOptionValue(args, "--config-dir");
  if (!path.isAbsolute(configDirectory)) {
    throw new Error("--config-dir must be an existing absolute directory.");
  }
  try {
    const resolved = fs.realpathSync.native(configDirectory);
    if (
      !fs.statSync(resolved).isDirectory()
      || !fs.statSync(path.join(resolved, "sixtytwo.yaml")).isFile()
    ) {
      throw new Error("invalid qualification configuration");
    }
  } catch {
    throw new Error(
      "--config-dir must exist and contain a regular sixtytwo.yaml before any process is started."
    );
  }
}

function parseArgs(argv, environment = process.env) {
  const args = [...argv];

View on GitHub (pinned to 01e15490f0)

Solutions

  1. Pass an absolute path: `--config-dir /home/operator/sixtytwo-config` (or `$(pwd)/config` if you want it relative to cwd).
  2. Expand `~` before passing: `--config-dir "$HOME/sixtytwo-config"` — Node will not expand it for you.
  3. Confirm the directory already contains a regular sixtytwo.yaml file, since the next check (ito.js:126-138) verifies that.

Example fix

// before
$ ecc ito evals --cluster c1 --live-sixtytwo --nodes n1,n2 --config-dir ./cfg
// after
$ ecc ito evals --cluster c1 --live-sixtytwo --nodes n1,n2 --config-dir "$PWD/cfg"
Defensive patterns

Strategy: validation

Validate before calling

const path = require('path');
function assertConfigDirAbsolute(configDirectory) {
  if (typeof configDirectory !== 'string' || !path.isAbsolute(configDirectory)) {
    throw new Error(`--config-dir must be an existing absolute directory (got: ${configDirectory})`);
  }
  return configDirectory;
}
// before calling `ecc ito evals`
assertConfigDirAbsolute(process.env.ITO_CONFIG_DIR);

Prevention

When it happens

Trigger: Calling `ecc ito evals --cluster <id> --live-sixtytwo --nodes <list> --config-dir ./config` or `--config-dir config/sixtytwo` (any relative path). ITO_ENABLE_SIXTYTWO_LIVE=1, --live-sixtytwo, --cluster, and --nodes must already have passed their preceding checks at ito.js:107-121 for execution to reach line 123.

Common situations: Operator runs the evals subcommand from the repo root and passes a relative config path out of habit (e.g. `--config-dir ./sixtytwo-config`). Shell expansion of `~` also produces a relative-looking token (`~/config`) because Node's path.isAbsolute treats `~` literally, not as $HOME.

Related errors


AI-assisted analysis of affaan-m/ECC@01e15490f0 (2026-08-13). Data as JSON: /api/errors/516c85656c41e461. Report an issue: GitHub.