{"record":{"id":"0ab9cb6c6ba7a7b7","repo":"vercel/turborepo","slug":"found-both-turbo-json-and-turbo-jsonc-in-the-same-0ab9cb","errorCode":null,"errorMessage":"Found both turbo.json and turbo.jsonc in the same directory: ${dirPath}\nPlease use either turbo.json or turbo.jsonc, but not both.","messagePattern":"Found both turbo\\.json and turbo\\.jsonc in the same directory: (.+?)\nPlease use either turbo\\.json or turbo\\.jsonc, but not both\\.","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/turbo-utils/src/get-turbo-configs.ts","lineNumber":288,"sourceCode":"\n        const workspaceName = packageJsonContent.name;\n        const workspacePath = path.dirname(configPath);\n        const isWorkspaceRoot = workspacePath === turboRoot;\n\n        // Try and get turbo.json or turbo.jsonc\n        const {\n          configPath: turboConfigPath,\n          configExists,\n          error\n        } = resolveTurboConfigPath(workspacePath);\n\n        let rawTurboJson = null;\n        let turboConfig: SchemaV1 | undefined;\n\n        try {\n          if (error) {\n            logger.error(error);\n            throw new Error(error);\n          }\n\n          if (configExists && turboConfigPath) {\n            rawTurboJson = fs.readFileSync(turboConfigPath, \"utf8\");\n          }\n\n          if (rawTurboJson) {\n            turboConfig = JSON5.parse(rawTurboJson);\n\n            if (turboConfig) {\n              // basic config validation\n              if (isWorkspaceRoot) {\n                // invalid - root config with extends\n                if (\"extends\" in turboConfig) {\n                  continue;\n                }\n              } else if (!(\"extends\" in turboConfig)) {\n                // invalid - workspace config with no extends","sourceCodeStart":270,"sourceCodeEnd":306,"githubUrl":"https://github.com/vercel/turborepo/blob/f9245100cf0d31d96628804ead485f6bf226e55a/packages/turbo-utils/src/get-turbo-configs.ts#L270-L306","documentation":"A second guard in get-turbo-configs.ts, on the per-workspace resolution path: after resolveTurboConfigPath returns a configPath for a workspace, the loader detects that the workspace directory holds both turbo.json and turbo.jsonc and throws the same 'use one, not both' error. The first guard (line 196) covers the multi-config discovery loop; this one covers the single-workspace resolve path.","triggerScenarios":"Calling the workspace-config resolution API for a workspacePath whose directory physically contains turbo.json and turbo.jsonc at the same time; resolveTurboConfigPath surfaces the ambiguity and the error is re-thrown after being logged.","commonSituations":"Same as the sibling error: converting a repo to turbo.jsonc without deleting turbo.json, sync tools or generators that add turbo.json into packages already configured with turbo.jsonc, or platform case-insensitivity making what looks like one file into two.","solutions":["Delete one config file in the affected workspace directory listed in the message","Search the whole repo for duplicates: find . -name 'turbo.json*' -not -path '*/node_modules/*' and ensure each directory has exactly one","If migrating to JSONC repo-wide, script the rename and git rm the old files in one commit","Add a CI check that fails when a directory contains both filenames"],"exampleFix":"# before\npackages/app/turbo.json\npackages/app/turbo.jsonc\n# Error: Found both turbo.json and turbo.jsonc in the same directory: /repo/packages/app\n\n# after\nrm packages/app/turbo.json\n# single turbo.jsonc remains","handlingStrategy":"validation","validationCode":"import { existsSync, readdirSync } from \"node:fs\";\n\nfunction findDuplicateConfigDirs(root: string): string[] {\n  return readdirSync(root, { recursive: true, withFileTypes: true })\n    .filter((d) => d.isDirectory() && d.name !== \"node_modules\")\n    .map((d) => join(d.path, d.name))\n    .filter((dir) => existsSync(join(dir, \"turbo.json\")) && existsSync(join(dir, \"turbo.jsonc\")));\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["After any workspace scaffold/copy step, assert each directory holds exactly one turbo config","Treat config duplication as a merge artifact and check 'git ls-files | grep turbo.json' in review","Add a preflight check in CI before running turbo commands"],"tags":["configuration","turborepo","turbo-json","workspace"],"backgroundTag":"config-file-conflict","analyzedSha":"f9245100cf0d31d96628804ead485f6bf226e55a","analyzedAt":"2026-08-17T10:46:15.696Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}