{"record":{"id":"b70d13a7261152a5","repo":"angular/angular-cli","slug":"file-replacement-replace-does-not-exist","errorCode":null,"errorMessage":"File replacement (replace) does not exist","messagePattern":"File replacement \\(replace\\) does not exist","errorType":"exception","errorClass":"MissingFileReplacementException","httpStatus":null,"severity":"error","filePath":"packages/angular_devkit/build_angular/src/utils/normalize-file-replacements.ts","lineNumber":42,"sourceCode":"export function normalizeFileReplacements(\n  fileReplacements: FileReplacement[],\n  workspaceRoot: string,\n): NormalizedFileReplacement[] {\n  if (fileReplacements.length === 0) {\n    return [];\n  }\n\n  const normalizedReplacement = fileReplacements.map((replacement) =>\n    normalizeFileReplacement(replacement, workspaceRoot),\n  );\n\n  for (const { replace, with: replacementWith } of normalizedReplacement) {\n    if (!existsSync(replacementWith)) {\n      throw new MissingFileReplacementException(replacementWith);\n    }\n\n    if (!existsSync(replace)) {\n      throw new MissingFileReplacementException(replace);\n    }\n  }\n\n  return normalizedReplacement;\n}\n\nfunction normalizeFileReplacement(\n  fileReplacement: FileReplacement,\n  root: string,\n): NormalizedFileReplacement {\n  let replacePath: string;\n  let withPath: string;\n  if (fileReplacement.src && fileReplacement.replaceWith) {\n    replacePath = fileReplacement.src;\n    withPath = fileReplacement.replaceWith;\n  } else if (fileReplacement.replace && fileReplacement.with) {\n    replacePath = fileReplacement.replace;\n    withPath = fileReplacement.with;","sourceCodeStart":24,"sourceCodeEnd":60,"githubUrl":"https://github.com/angular/angular-cli/blob/bb72145f9ab45aee29f523236b3a25cd0813a841/packages/angular_devkit/build_angular/src/utils/normalize-file-replacements.ts#L24-L60","documentation":"The counterpart check of normalizeFileReplacements: after the `with` file is verified, the `replace` (the file being replaced in the compilation, typically src/environments/environment.ts) must also exist on disk; otherwise MissingFileReplacementException is thrown for that path. Both sides of a replacement must be real files since webpack must read one and substitute the other.","triggerScenarios":"ng build with a fileReplacements entry whose \"replace\" path (resolved against workspaceRoot) does not exist — usually the base environment.ts was deleted/renamed, or the path points to the wrong project directory in a monorepo.","commonSituations":"Deleting the base environment file while keeping prod replacement entries, moving environments under a different folder, or multi-project repos where the replacement was copied between projects without adjusting the path.","solutions":["Recreate or restore the file referenced by \"replace\" (e.g. src/environments/environment.ts) so it exists in the workspace.","Update the \"replace\" path in angular.json to the actual base file location.","Audit all fileReplacements entries across configurations with ls or a script before building."],"exampleFix":"// before (angular.json)\n\"fileReplacements\": [{ \"replace\": \"src/config/environment.ts\", \"with\": \"src/config/environment.prod.ts\" }]\n// after (base file lives at src/environments/environment.ts)\n\"fileReplacements\": [{ \"replace\": \"src/environments/environment.ts\", \"with\": \"src/config/environment.prod.ts\" }]","handlingStrategy":"validation","validationCode":"// Check before running the build\nconst { existsSync } = require('fs');\nconst { resolve } = require('path');\nfor (const fr of schema.fileReplacements ?? []) {\n  if (!existsSync(resolve(workspaceRoot, fr.replace))) {\n    throw new Error(`fileReplacements 'replace' base file missing: ${fr.replace}`);\n  }\n}","typeGuard":null,"tryCatchPattern":"try {\n  await runBuild(schema);\n} catch (err) {\n  if (err?.constructor?.name === 'MissingFileReplacementException' || /does not exist/.test(err?.message ?? '')) {\n    console.error('The base file to replace is missing; restore it or update the fileReplacements path.');\n    process.exitCode = 1;\n  } else throw err;\n}","preventionTips":["Keep a stable src/environments/environment.ts base file that all replacements target.","When removing an environment file, remove every fileReplacements entry referencing it in the same change.","Add a prebuild script verifying both sides of each replacement exist."],"tags":["angular-cli","file-replacements","missing-file","configuration"],"backgroundTag":"missing-file-replacement","analyzedSha":"bb72145f9ab45aee29f523236b3a25cd0813a841","analyzedAt":"2026-08-30T02:47:34.745Z","schemaVersion":2},"datasetVersion":"2026-08-30T08:17:16.595Z"}