{"record":{"id":"98e33d39ecb2e4b3","repo":"angular/angular-cli","slug":"cannot-statically-analyze-bootstrapapplication-cal","errorCode":null,"errorMessage":"Cannot statically analyze bootstrapApplication call in ${bootstrapCall.getSourceFile().fileName}","messagePattern":"Cannot statically analyze bootstrapApplication call in (.+?)","errorType":"exception","errorClass":"SchematicsException","httpStatus":null,"severity":"error","filePath":"packages/schematics/angular/utility/standalone/rules.ts","lineNumber":198,"sourceCode":"      }`,\n    );\n  }\n\n  if (appConfig) {\n    addProvidersExpressionToAppConfig(tree, appConfig, expression);\n\n    return;\n  }\n\n  const newAppConfig = `, {\\n${' '.repeat(2)}providers: [${expression}]\\n}`;\n  let targetCall: ts.CallExpression;\n\n  if (bootstrapCall.arguments.length === 1) {\n    targetCall = bootstrapCall;\n  } else if (isMergeAppConfigCall(bootstrapCall.arguments[1])) {\n    targetCall = bootstrapCall.arguments[1];\n  } else {\n    throw new SchematicsException(\n      `Cannot statically analyze bootstrapApplication call in ${\n        bootstrapCall.getSourceFile().fileName\n      }`,\n    );\n  }\n\n  applyChangesToFile(tree, mainFilePath, [\n    insertAfterLastOccurrence(\n      targetCall.arguments,\n      newAppConfig,\n      mainFilePath,\n      targetCall.getEnd() - 1,\n    ),\n  ]);\n}\n\n/**\n * Adds a string expression to an app config object.","sourceCodeStart":180,"sourceCodeEnd":216,"githubUrl":"https://github.com/angular/angular-cli/blob/bb72145f9ab45aee29f523236b3a25cd0813a841/packages/schematics/angular/utility/standalone/rules.ts#L180-L216","documentation":"insertStandaloneRootProvider determines where to inject the new provider: either the bootstrapApplication call itself (1 argument) or its second argument when that is a `mergeApplicationConfig(...)` call. Any other argument shape is not statically analyzable, so the schematic refuses to guess and throws.","triggerScenarios":"Adding a provider to a standalone app whose second bootstrapApplication argument is neither an object literal / identifiable app config nor a mergeApplicationConfig(...) call — e.g. a function call, conditional expression, or variable from an unresolvable import.","commonSituations":"Custom config factories: `bootstrapApplication(App, createConfig())`; configs assembled with dynamic spreads or imported via complex re-exports; obfuscated/generated entry files.","solutions":["Refactor main.ts to pass a literal object or mergeApplicationConfig(...) call as the second argument, then re-run the schematic.","Manually add the provider into your config factory and skip the automated insert.","Move the config expression inline (e.g. `bootstrapApplication(App, { providers: [...] })`)."],"exampleFix":"// before\nbootstrapApplication(AppComponent, createAppConfig());\n// after\nbootstrapApplication(AppComponent, mergeApplicationConfig(createAppConfig(), { providers: [provideX()] }));","handlingStrategy":"validation","validationCode":"const main = fs.readFileSync('src/main.ts', 'utf8');\nconst m = main.match(/bootstrapApplication\\([^)]*\\)/);\nif (m && !/mergeApplicationConfig|\\{\\s*providers/.test(m[0])) {\n  console.warn('Second bootstrapApplication argument is not statically analyzable.');\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Keep the second bootstrapApplication argument a literal object or mergeApplicationConfig(...) call.","Avoid config factory functions or conditional expressions in main.ts.","Add providers manually when using dynamic config construction."],"tags":["angular","standalone","schematics","static-analysis"],"backgroundTag":"unanalyzable-bootstrap-call","analyzedSha":"bb72145f9ab45aee29f523236b3a25cd0813a841","analyzedAt":"2026-08-30T02:47:34.745Z","schemaVersion":2},"datasetVersion":"2026-08-30T08:17:16.595Z"}