{"record":{"id":"3765263f9154a75e","repo":"angular/angular","slug":"cannot-run-service-migration-outside-of-the-curren","errorCode":null,"errorMessage":"Cannot run service migration outside of the current project.","messagePattern":"Cannot run service migration outside of the current project\\.","errorType":"exception","errorClass":"SchematicsException","httpStatus":null,"severity":"error","filePath":"packages/core/schematics/ng-generate/service-migration/index.ts","lineNumber":29,"sourceCode":"import ts from 'typescript';\n\nimport {normalizePath} from '../../utils/change_tracker';\nimport {canMigrateFile, createMigrationProgram} from '../../utils/typescript/compiler_host';\n\nimport {migrateFile} from './migration';\nimport {getProjectTsConfigPaths} from '../../utils/project_tsconfig_paths';\n\ninterface Options {\n  path: string;\n}\n\nexport function migrate(options: Options): Rule {\n  return async (tree: Tree, context: SchematicContext) => {\n    const basePath = process.cwd();\n    let pathToMigrate: string | undefined;\n    if (options.path) {\n      if (options.path.startsWith('..')) {\n        throw new SchematicsException(\n          'Cannot run service migration outside of the current project.',\n        );\n      }\n      pathToMigrate = normalizePath(join(basePath, options.path));\n    }\n\n    const {buildPaths, testPaths} = await getProjectTsConfigPaths(tree);\n    const allPaths = [...buildPaths, ...testPaths];\n\n    if (!allPaths.length) {\n      context.logger.warn('Could not find any tsconfig file. Cannot run the service migration.');\n      return;\n    }\n\n    let sourceFilesCount = 0;\n\n    for (const tsconfigPath of allPaths) {\n      const program = createMigrationProgram(tree, tsconfigPath, basePath);","sourceCodeStart":11,"sourceCodeEnd":47,"githubUrl":"https://github.com/angular/angular/blob/51cb07e98081ab7e4e84a9e0949266a8e19cca84/packages/core/schematics/ng-generate/service-migration/index.ts#L11-L47","documentation":"The service migration schematic (migrating providedIn: 'root' services, etc. as part of the standalone/inject family) applies the same cwd escape guard as the inject migration: a truthy options.path starting with '..' is rejected so files outside the current project are never touched.","triggerScenarios":"Running ng generate service-migration --path ../lib or any --path value whose first characters are '..'. Only a truthy --path is checked; omitting the flag skips the guard.","commonSituations":"Running the migration from a nested folder while pointing at a parent directory; trying to cover a shared library from the app workspace; copied CI commands with hardcoded relative paths.","solutions":["Run the command from the target project's root directory.","Use a --path that does not start with '..' (e.g. ./src or ./projects/shared).","Run a separate invocation inside each workspace of a monorepo."],"exampleFix":"# before\nng generate service-migration --path ../shared\n\n# after (from the workspace root)\nng generate service-migration --path ./projects/shared","handlingStrategy":"validation","validationCode":"function assertSafeMigrationPath(pathOpt?: string): void {\n  if (pathOpt && pathOpt.startsWith('..')) {\n    throw new Error(`Refusing migration path outside project: ${pathOpt}`);\n  }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["cd to the project root before running service/inject migrations.","Keep --path project-relative (./src, ./projects/x).","Standardize migration commands in package.json scripts so paths are fixed and reviewed."],"tags":["schematics","service-migration","path","cli"],"backgroundTag":"schematic-path-outside-project","analyzedSha":"51cb07e98081ab7e4e84a9e0949266a8e19cca84","analyzedAt":"2026-08-22T07:04:54.531Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}