{"record":{"id":"27f066f8f966d8e0","repo":"angular/angular-cli","slug":"outputpath-for-projectname-target-target-is","errorCode":null,"errorMessage":"outputPath for ${projectName} ${target} target is not a string.","messagePattern":"outputPath for (.+?) (.+?) target is not a string\\.","errorType":"exception","errorClass":"SchematicsException","httpStatus":null,"severity":"error","filePath":"packages/schematics/angular/ssr/index.ts","lineNumber":65,"sourceCode":"const DEFAULT_MEDIA_DIR = 'media';\nconst DEFAULT_SERVER_DIR = 'server';\n\nasync function getLegacyOutputPaths(\n  host: Tree,\n  projectName: string,\n  target: 'server' | 'build',\n): Promise<string> {\n  // Generate new output paths\n  const workspace = await readWorkspace(host);\n  const project = workspace.projects.get(projectName);\n  const architectTarget = project?.targets.get(target);\n  if (!architectTarget?.options) {\n    throw new SchematicsException(`Cannot find 'options' for ${projectName} ${target} target.`);\n  }\n\n  const { outputPath } = architectTarget.options;\n  if (typeof outputPath !== 'string') {\n    throw new SchematicsException(\n      `outputPath for ${projectName} ${target} target is not a string.`,\n    );\n  }\n\n  return outputPath;\n}\n\nasync function getApplicationBuilderOutputPaths(\n  host: Tree,\n  projectName: string,\n): Promise<{ browser: string; server: string; base: string }> {\n  // Generate new output paths\n  const target = 'build';\n  const workspace = await readWorkspace(host);\n  const project = workspace.projects.get(projectName);\n  const architectTarget = project?.targets.get(target);\n\n  if (!architectTarget?.options) {","sourceCodeStart":47,"sourceCodeEnd":83,"githubUrl":"https://github.com/angular/angular-cli/blob/bb72145f9ab45aee29f523236b3a25cd0813a841/packages/schematics/angular/ssr/index.ts#L47-L83","documentation":"The SSR schematic found `options` on the build target but its `outputPath` is not a plain string — the schematic only supports string output paths when computing legacy browser/server dist directories. It throws to avoid deriving wrong paths from an object-shaped outputPath.","triggerScenarios":"Running the ssr schematic against a project whose build target sets `outputPath` as an object like `{\"base\":\"dist/app\",\"browser\":\"...\"}` (the application-builder form) while the project is detected as using the legacy builder path, or when outputPath is missing/another non-string type.","commonSituations":"Mixed workspace after Angular 17 migration where some targets use the new application builder; hand-copied outputPath config from another project; typos making outputPath an array or object in a legacy project.","solutions":["Change `outputPath` in the target's `options` to a plain string, e.g. \"outputPath\": \"dist/my-app\".","If the project uses the @angular-devkit/build-angular:application builder, ensure the builder type is set correctly so the schematic takes the application-builder path instead.","Migrate the project to the application builder (`ng update` or manually switch builder to `@angular-devkit/build-angular:application`)."],"exampleFix":"// before (angular.json, legacy project)\n\"outputPath\": { \"base\": \"dist/my-app\" }\n// after\n\"outputPath\": \"dist/my-app\"","handlingStrategy":"validation","validationCode":"const opts = workspace.projects.get(projectName)?.targets.get('build')?.options;\nif (typeof opts?.outputPath !== 'string') {\n  console.warn('Legacy build target must use a string outputPath before adding SSR.');\n}","typeGuard":"function isStringOutputPath(v: unknown): v is string {\n  return typeof v === 'string' && v.length > 0;\n}","tryCatchPattern":"try {\n  await ngAddSsr(projectName);\n} catch (e) {\n  if (String(e?.message).includes('outputPath') && String(e?.message).includes('is not a string')) {\n    console.error('Set outputPath to a plain string in angular.json build target options.');\n  }\n  throw e;\n}","preventionTips":["Use string outputPath for legacy (browser/webpack) builder projects.","If using the application builder's object form, ensure the builder is @angular-devkit/build-angular:application so the schematic takes the right path.","Migrate to the application builder via ng update before adding SSR.","Validate angular.json against the builder schema with a build run."],"tags":["angular","schematics","ssr","angular-json","output-path"],"backgroundTag":"invalid-output-path-type","analyzedSha":"bb72145f9ab45aee29f523236b3a25cd0813a841","analyzedAt":"2026-08-30T02:47:34.745Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}