{"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":"validation","errorClass":"Error","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/9f94a7d215b3881942527dd526afa3fc650869d5/packages/turbo-utils/src/get-turbo-configs.ts#L270-L306","documentation":"getWorkspaceConfigs() resolves each workspace's turbo config via resolveTurboConfigPath(); when that resolver detects both turbo.json and turbo.jsonc in the same workspace directory it returns an error string, which this code logs and rethrows. Same root cause as the getTurboConfigs() variant, but hit while enumerating workspaces during package.json discovery (editor tooling, turbo gen, workspace introspection).","triggerScenarios":"A workspace directory containing both turbo.json and turbo.jsonc, encountered while getWorkspaceConfigs() iterates every workspace package.json under the turbo root.","commonSituations":"IDE/LSP or generator runs failing after a partial migration to .jsonc; generated workspaces containing a stale turbo.json next to a hand-written turbo.jsonc.","solutions":["In the offending workspace directory, remove either turbo.json or turbo.jsonc so only one exists","Merge any differing settings into the file you keep before deleting the other","Add a repo lint/grep in CI to catch duplicated turbo configs"],"exampleFix":"# before\nls apps/web # => turbo.json turbo.jsonc\n\n# after\ngit rm apps/web/turbo.json # keep turbo.jsonc","handlingStrategy":"validation","validationCode":"import { existsSync } from \"node:fs\";\nimport path from \"node:path\";\n\nconst dirs = workspacePaths; // from package.json discovery\nconst conflicts = dirs.filter(\n  (d) => existsSync(path.join(d, \"turbo.json\")) && existsSync(path.join(d, \"turbo.jsonc\"))\n);\nif (conflicts.length) throw new Error(`Conflicting turbo configs in: ${conflicts.join(\", \")}`);","typeGuard":null,"tryCatchPattern":"try {\n  getWorkspaceConfigs(cwd);\n} catch (e) {\n  if (e instanceof Error && e.message.includes(\"Found both turbo.json and turbo.jsonc\")) {\n    // the message names the directory; remove one file and retry\n  } else throw e;\n}","preventionTips":["During .jsonc migrations, git rm the old file atomically with adding the new one","Run `find . \\( -name turbo.json -o -name turbo.jsonc \\)` before pushing workspace changes","Codemods that write turbo.json should first check for an existing turbo.jsonc"],"tags":["config","turborepo","file-conflict","workspace-discovery"],"backgroundTag":"conflicting-config-files","analyzedSha":"9f94a7d215b3881942527dd526afa3fc650869d5","analyzedAt":"2026-08-16T19:47:29.531Z","schemaVersion":2},"datasetVersion":"2026-08-16T23:17:17.608Z"}