{"record":{"id":"19df54d34c04fe11","repo":"angular/angular-cli","slug":"invalid-record-instance","errorCode":null,"errorMessage":"Invalid record instance.","messagePattern":"Invalid record instance\\.","errorType":"exception","errorClass":"InvalidUpdateRecordException","httpStatus":null,"severity":"error","filePath":"packages/angular_devkit/schematics/src/tree/host-tree.ts","lineNumber":409,"sourceCode":"      throw new FileDoesNotExistException(path);\n    }\n\n    return UpdateRecorderBase.createFromFileEntry(entry);\n  }\n  commitUpdate(record: UpdateRecorder): void {\n    if (record instanceof UpdateRecorderBase) {\n      const path = record.path;\n      const entry = this.get(path);\n      if (!entry) {\n        throw new ContentHasMutatedException(path);\n      } else {\n        const newContent = record.apply(entry.content);\n        if (!newContent.equals(entry.content)) {\n          this.overwrite(path, newContent);\n        }\n      }\n    } else {\n      throw new InvalidUpdateRecordException();\n    }\n  }\n\n  // Structural methods.\n  create(path: string, content: Buffer | string): void {\n    const c = typeof content == 'string' ? Buffer.from(content) : content;\n    this._record.create(this._normalizePath(path), c as {} as virtualFs.FileBuffer).subscribe();\n  }\n  delete(path: string): void {\n    this._recordSync.delete(this._normalizePath(path));\n  }\n  rename(from: string, to: string): void {\n    this._recordSync.rename(this._normalizePath(from), this._normalizePath(to));\n  }\n\n  apply(action: Action, strategy?: MergeStrategy): void {\n    throw new SchematicsException('Apply not implemented on host trees.');\n  }","sourceCodeStart":391,"sourceCodeEnd":427,"githubUrl":"https://github.com/angular/angular-cli/blob/bb72145f9ab45aee29f523236b3a25cd0813a841/packages/angular_devkit/schematics/src/tree/host-tree.ts#L391-L427","documentation":"HostTree.commitUpdate only accepts records that are instanceof UpdateRecorderBase (the base class of UpdateRecorder). Passing anything else — a plain object, a recorder from an incompatible Tree implementation, or a non-recorder value — throws InvalidUpdateRecordException. This is a runtime type check on the commitUpdate API surface.","triggerScenarios":"Calling tree.commitUpdate(x) with a value not produced by tree.beginUpdate()/tree.recorder(); mixing recorders across different Tree implementations or across library versions where the class identity differs (e.g. two bundled copies of @angular-devkit/schematics); committing a mock or custom UpdateRecorder not extending UpdateRecorderBase.","commonSituations":"Duplicate @angular-devkit/schematics installations causing instanceof to fail even for 'real' recorders (same Jest instanceof pitfall noted in this file); passing the string returned from a wrong API; committing an already-committed or hand-rolled recorder object.","solutions":["Only pass the object returned by tree.beginUpdate(path) or tree.beginUpdate on the same tree instance.","Check for duplicate @angular-devkit/schematics versions in node_modules (npm ls) and deduplicate so instanceof matches.","Create custom recorders by extending UpdateRecorderBase, not by implementing the interface ad hoc."],"exampleFix":"// before\ntree.commitUpdate({ path, apply: c => c } as any);\n// after\nconst record = tree.beginUpdate(filePath);\n// ...edits...\ntree.commitUpdate(record);","handlingStrategy":"type-guard","validationCode":"import { UpdateRecorderBase } from '@angular-devkit/schematics/src/update/update-recorder';\nconst isCommittable = record instanceof UpdateRecorderBase;","typeGuard":"function isRealRecorder(r: unknown): r is UpdateRecorderBase {\n  return r instanceof UpdateRecorderBase;\n}","tryCatchPattern":"try {\n  tree.commitUpdate(record);\n} catch (e) {\n  if ((e as Error).message === 'Invalid record instance.') {\n    // record came from another tree/duplicate package: recreate via tree.beginUpdate\n  } else throw e;\n}","preventionTips":["Only commit recorders obtained from the same tree's beginUpdate/recorder","Check `npm ls @angular-devkit/schematics` for duplicate versions that break instanceof","Never hand-roll objects cast to UpdateRecorder","Use tree.recorder(path) convenience API instead of custom recorders"],"tags":["type-error","update-recorder","instanceof","schematics"],"backgroundTag":"invalid-update-record","analyzedSha":"bb72145f9ab45aee29f523236b3a25cd0813a841","analyzedAt":"2026-08-30T02:47:34.745Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}