vercel/turborepo · warning · Error

Could not find telemetry config directory

Error message

Could not find telemetry config directory

What it means

utils.defaultConfigPath() in @turbo/telemetry computes the telemetry config path: it uses TURBO_CONFIG_DIR_PATH if set, otherwise the OS config directory via dirs-next's configDir(). If neither yields a directory (configDir returns null when XDG_CONFIG_HOME and HOME are unset on Linux, or the platform's known-folder lookup fails), it throws this error. TelemetryConfig.fromDefaultConfig catches it and returns undefined, silently disabling telemetry, so it surfaces only when defaultConfigPath is used directly.

Source

Thrown at packages/turbo-telemetry/src/utils.ts:21

import path from "node:path";
import { configDir } from "dirs-next";
import type { PackageInfo } from "./events/types";

function buildUserAgent(packageInfo: PackageInfo): string {
  const nodeVersion = process.version;
  const operatingSystem = os.type();
  const architecture = os.arch();

  return `${packageInfo.name} ${packageInfo.version} ${nodeVersion} ${operatingSystem} ${architecture}`;
}

async function defaultConfigPath() {
  const dir = process.env.TURBO_CONFIG_DIR_PATH
    ? process.env.TURBO_CONFIG_DIR_PATH
    : await configDir();

  if (!dir) {
    throw new Error("Could not find telemetry config directory");
  }

  return path.join(dir, "turborepo", "telemetry.json");
}

function oneWayHashWithSalt({ input, salt }: { input: string; salt: string }) {
  return crypto.createHash("sha256").update(`${salt}${input}`).digest("hex");
}

// Exported asn an object instead of export keyword, so that these functions
// can be mocked in tests.
export default {
  buildUserAgent,
  oneWayHashWithSalt,
  defaultConfigPath
};

View on GitHub (pinned to 9f94a7d215)

Solutions

  1. Set TURBO_CONFIG_DIR_PATH to an existing, writable directory
  2. Ensure HOME (and optionally XDG_CONFIG_HOME on Linux) is exported for the process
  3. If telemetry is unwanted, set TURBO_TELEMETRY_DISABLED=1 rather than deleting HOME

Example fix

# before: no HOME, configDir() returns null
export TURBO_CONFIG_DIR_PATH=/root/.config

# after: telemetry config resolves to /root/.config/turborepo/telemetry.json
Defensive patterns

Strategy: validation

Validate before calling

function hasConfigHome(): boolean {
  return Boolean(process.env.TURBO_CONFIG_DIR_PATH || process.env.XDG_CONFIG_HOME || process.env.HOME);
}

if (!hasConfigHome()) {
  process.env.TURBO_CONFIG_DIR_PATH = "/tmp/turbo-config"; // writable fallback
}

Try / catch

try {
  const path = await utils.defaultConfigPath();
} catch (e) {
  if (e instanceof Error && e.message === "Could not find telemetry config directory") {
    // set TURBO_CONFIG_DIR_PATH and retry, or proceed without telemetry
  } else throw e;
}

Prevention

When it happens

Trigger: TURBO_CONFIG_DIR_PATH unset or empty AND configDir() returning null — typically a Linux process with both HOME and XDG_CONFIG_HOME removed from the environment, or a daemon/service running without a user session profile.

Common situations: Minimal Docker/CI containers that strip HOME; test runners with sanitized environments; systemd services or cron jobs without User=/environment set.

Related errors


AI-assisted analysis of vercel/turborepo@9f94a7d215 (2026-08-16). Data as JSON: /api/errors/fd4945caba83ad8d. Report an issue: GitHub.