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
- Set TURBO_CONFIG_DIR_PATH to an existing, writable directory
- Ensure HOME (and optionally XDG_CONFIG_HOME on Linux) is exported for the process
- 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
- Set TURBO_CONFIG_DIR_PATH explicitly in containers, CI, and daemons
- Keep HOME exported in minimal images that run node tooling
- Treat telemetry as optional: failures to locate its config should never fail your build
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
- Config is invalid.
- Invalid task name found in turbo.json.
- May not specify workspace name in non-root turbo.json
- No config at "${configPath}"
- Unable to load generators
AI-assisted analysis of vercel/turborepo@9f94a7d215 (2026-08-16).
Data as JSON: /api/errors/fd4945caba83ad8d.
Report an issue: GitHub.