{"record":{"id":"642700600bb69858","repo":"denoland/deno","slug":"cannot-generate-declarations-for-files-with-differ","errorCode":null,"errorMessage":"Cannot generate declarations for files with different compiler option scopes.\n'{}' uses scope '{}' but '{}' uses scope '{}'.\nSeparate these files into different invocations.","messagePattern":"Cannot generate declarations for files with different compiler option scopes\\.\n'(.+?)' uses scope '(.+?)' but '(.+?)' uses scope '(.+?)'\\.\nSeparate these files into different invocations\\.","errorType":"validation","errorClass":"AnyError","httpStatus":null,"severity":"error","filePath":"cli/tools/transpile.rs","lineNumber":278,"sourceCode":"      specifiers,\n      crate::graph_util::BuildGraphWithNpmOptions {\n        is_dynamic: false,\n        loader: None,\n        npm_caching: cli_options.default_npm_caching_strategy(),\n      },\n    )\n    .await?;\n\n  // Validate that all files share the same compiler options scope, since\n  // TSC type-checks all files in a single pass.\n  let compiler_options_resolver = factory.compiler_options_resolver()?;\n  let first_specifier = &root_names[0].0;\n  let (first_key, _) =\n    compiler_options_resolver.entry_for_specifier(first_specifier);\n  for (specifier, _) in root_names.iter().skip(1) {\n    let (key, _) = compiler_options_resolver.entry_for_specifier(specifier);\n    if key != first_key {\n      anyhow::bail!(\n        \"Cannot generate declarations for files with different compiler option scopes.\\n\\\n         '{}' uses scope '{}' but '{}' uses scope '{}'.\\n\\\n         Separate these files into different invocations.\",\n        first_specifier,\n        first_key,\n        specifier,\n        key,\n      );\n    }\n  }\n\n  let type_checker = factory.type_checker().await?;\n  let result = type_checker.emit_declarations(\n    Arc::new(graph),\n    root_names,\n    cli_options.ts_type_lib_window(),\n  )?;\n","sourceCodeStart":260,"sourceCodeEnd":296,"githubUrl":"https://github.com/denoland/deno/blob/9ad36f7a2cce60488e6ec52283efb32efddaf93a/cli/tools/transpile.rs#L260-L296","documentation":"Thrown by `deno cache` / declaration emit when the set of root files being type-checked in a single TSC pass do not all resolve to the same compiler-options scope. Deno maps every specifier to a compiler options entry (keyed by the effective tsconfig/deno.json settings that cover it, e.g. a workspace member's own compilerOptions). Because TSC type-checks all root names in one invocation, mixing scopes would produce wrong declarations, so Deno refuses and asks you to split the invocation.","triggerScenarios":"Running one command that emits declarations for multiple entrypoints where at least one file is covered by a different deno.json/tsconfig scope: e.g. a Deno workspace whose members declare differing `compilerOptions`, or entrypoints that resolve through node_modules/JSR packages carrying their own settings. The loop at cli/tools/transpile.rs compares each root_name's `entry_for_specifier()` key against the first file's key and bails on the first mismatch.","commonSituations":"Adopting Deno workspaces with per-member tsconfig overrides; adding a second entrypoint (test file, bench file) that sits in another workspace member; refactoring a monorepo so one import crosses a compilerOptions boundary; Deno version upgrades that changed how scopes are keyed.","solutions":["Split the work: run a separate `deno cache` (or emit) invocation per scope, e.g. one per workspace member, so each invocation's root names share one scope.","Align the scopes: make the conflicting deno.json / workspace-member `compilerOptions` identical (or delete the per-member override) so both files resolve to the same key.","Identify the two scopes named in the message (first file's scope vs the offending file's scope) and move the offending file under the config that owns the first entrypoint.","If you do not need declarations for the second file, drop it from the same invocation instead of mixing it in."],"exampleFix":"# before: one invocation, two scopes\ndeno cache --config memberA/deno.json memberA/mod.ts memberB/mod.ts\n# error: 'memberA/mod.ts' uses scope '...memberA/deno.json' but 'memberB/mod.ts' uses scope '...memberB/deno.json'\n\n# after: one invocation per scope\ndeno cache --config memberA/deno.json memberA/mod.ts\ndeno cache --config memberB/deno.json memberB/mod.ts","handlingStrategy":"validation","validationCode":"# group entrypoints by their deno.json/tsconfig scope before caching\n# (each workspace member gets its own invocation)\nfor member in memberA memberB; do\n  deno cache --config \"$member/deno.json\" \"$member\"/*.ts\ndone","typeGuard":null,"tryCatchPattern":"deno cache main.ts 2>&1 | grep -q \"different compiler option scopes\" && { echo \"split into per-scope invocations\"; exit 1; }","preventionTips":["One `deno cache`/emit invocation per workspace member or per tsconfig scope.","Keep compilerOptions consistent across workspace members unless a split is intended.","When adding a second entrypoint, confirm it is covered by the same deno.json as the first.","Read the two scope keys in the message — they name exactly which configs conflict."],"tags":["typescript","declarations","compiler-options","workspace","tsc"],"backgroundTag":"tsconfig-scope-conflict","analyzedSha":"9ad36f7a2cce60488e6ec52283efb32efddaf93a","analyzedAt":"2026-08-20T13:07:44.778Z","contentChangedAt":"2026-08-20T13:07:44.778Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}