vercel/turborepo · warning · Error
Config is invalid.
Error message
Config is invalid.
What it means
TelemetryConfig.validateConfig() parses a telemetry config object with a zod schema that requires telemetry_enabled (boolean), telemetry_id (string), telemetry_salt (string), with optional telemetry_alerted (string). Any mismatch throws this generic message and discards the underlying ZodError. In the normal read path (fromConfigPath) the error is caught and the corrupt telemetry.json is deleted and regenerated, so it only escapes when validateConfig is called directly.
Source
Thrown at packages/turbo-telemetry/src/config.ts:65
return undefined;
}
}
static async fromDefaultConfig(): Promise<TelemetryConfig | undefined> {
try {
const configPath = await utils.defaultConfigPath();
return TelemetryConfig.fromConfigPath(configPath);
} catch (e) {
return undefined;
}
}
static validateConfig(config: unknown): Config {
try {
return ConfigSchema.parse(config);
} catch (e) {
throw new Error("Config is invalid.");
}
}
static create({
configPath
}: {
configPath: string;
}): TelemetryConfig | undefined {
const RawTelemetryId = randomUUID();
const telemetrySalt = randomUUID();
const telemetryId = utils.oneWayHashWithSalt({
input: RawTelemetryId,
salt: telemetrySalt
});
const config = new TelemetryConfig({
configPath,
config: {View on GitHub (pinned to 9f94a7d215)
Solutions
- Delete the telemetry config file (e.g. ~/.config/turborepo/telemetry.json, or wherever TURBO_CONFIG_DIR_PATH points) — Turborepo recreates it on the next run
- Fix the file to match the schema: { "telemetry_enabled": true, "telemetry_id": "<uuid>", "telemetry_salt": "<uuid>" } with booleans, not strings
- If calling validateConfig yourself, parse with the same zod schema first so you see the real validation issues
Example fix
// before (invalid: string instead of boolean)
{ "telemetry_enabled": "false", "telemetry_id": "abc" }
// after
{ "telemetry_enabled": false, "telemetry_id": "abc", "telemetry_salt": "def" } Defensive patterns
Strategy: validation
Validate before calling
import { z } from "zod";
const TelemetrySchema = z.object({
telemetry_enabled: z.boolean(),
telemetry_id: z.string(),
telemetry_salt: z.string(),
telemetry_alerted: z.string().optional()
});
const parsed = TelemetrySchema.safeParse(rawConfig);
if (!parsed.success) console.error(parsed.error.issues); // real reason
else TelemetryConfig.validateConfig(parsed.data); Type guard
const isTelemetryConfig = (c: unknown): c is { telemetry_enabled: boolean; telemetry_id: string; telemetry_salt: string; telemetry_alerted?: string } =>
typeof c === "object" && c !== null &&
typeof (c as any).telemetry_enabled === "boolean" &&
typeof (c as any).telemetry_id === "string" &&
typeof (c as any).telemetry_salt === "string"; Try / catch
try {
TelemetryConfig.validateConfig(raw);
} catch (e) {
if (e instanceof Error && e.message === "Config is invalid.") {
// recover: delete config file and let TelemetryConfig.create regenerate it
} else throw e;
} Prevention
- Never hand-edit telemetry.json; use env vars (TURBO_TELEMETRY_DISABLED) to toggle telemetry
- Keep booleans as booleans when scripting against the file
- If reading the config programmatically, use TelemetryConfig.fromConfigPath which self-heals corrupt files
When it happens
Trigger: Calling TelemetryConfig.validateConfig(rawConfig) with an object that fails ConfigSchema.parse: missing or misspelled keys (telemetryId instead of telemetry_id), wrong types (telemetry_enabled: "true" instead of true), or a hand-edited file that is valid JSON but not valid telemetry config.
Common situations: Hand-editing ~/.config/turborepo/telemetry.json to disable telemetry with a string value; another tool truncating or rewriting the file; direct API use of validateConfig without pre-validation.
Related errors
- Could not find telemetry config directory
- 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/aad2eecf61eadeed.
Report an issue: GitHub.