{"record":{"id":"7586be0b7db05095","repo":"angular/angular-cli","slug":"tree-type-is-not-supported","errorCode":null,"errorMessage":"Tree type is not supported.","messagePattern":"Tree type is not supported\\.","errorType":"exception","errorClass":"SchematicsException","httpStatus":null,"severity":"error","filePath":"packages/angular_devkit/schematics/src/rules/base.ts","lineNumber":80,"sourceCode":"export function mergeWith(source: Source, strategy: MergeStrategy = MergeStrategy.Default): Rule {\n  return (tree, context) => {\n    return callSource(source, context).pipe(\n      map((sourceTree) => tree.merge(sourceTree, strategy || context.strategy)),\n      mapTo(tree),\n    );\n  };\n}\n\nexport function noop(): Rule {\n  return () => {};\n}\n\nexport function filter(predicate: FilePredicate<boolean>): Rule {\n  return (tree: Tree) => {\n    if (HostTree.isHostTree(tree)) {\n      return new FilterHostTree(tree, predicate);\n    } else {\n      throw new SchematicsException('Tree type is not supported.');\n    }\n  };\n}\n\nexport function asSource(rule: Rule): Source {\n  return (context) => callRule(rule, staticEmpty(), context);\n}\n\nexport function branchAndMerge(rule: Rule, strategy: MergeStrategy = MergeStrategy.Default): Rule {\n  return (tree, context) => {\n    return callRule(rule, tree.branch(), context).pipe(\n      map((branch) => tree.merge(branch, strategy || context.strategy)),\n      mapTo(tree),\n    );\n  };\n}\n\nexport function when(predicate: FilePredicate<boolean>, operator: FileOperator): FileOperator {","sourceCodeStart":62,"sourceCodeEnd":98,"githubUrl":"https://github.com/angular/angular-cli/blob/bb72145f9ab45aee29f523236b3a25cd0813a841/packages/angular_devkit/schematics/src/rules/base.ts#L62-L98","documentation":"The filter() rule only knows how to apply a FilePredicate to a HostTree. If the tree passed at execution time is not a HostTree (checked via HostTree.isHostTree), the rule cannot construct a FilterHostTree and throws SchematicsException. It protects against silently filtering trees with incompatible semantics.","triggerScenarios":"Using filter(predicate) inside a rule that receives a custom Tree implementation (e.g. a wrapped/subclassed tree or a FilterHostTree-hostile tree from another engine/adapter).","commonSituations":"Custom Tree implementations from third-party tooling; using filter on a tree produced via applyToSubtree with an exotic host; library versions where a custom host was introduced.","solutions":["Ensure the tree is a HostTree — operate on the underlying host tree instead of a custom Tree.","Replace filter() with manual visit/delete logic that works on any Tree implementation.","If wrapping trees (e.g. in a UnitTestTree), pass the underlying HostTree (tree.branch() or host access)."],"exampleFix":"// before\nreturn filter(p => p)(tree as any);\n// after\nif (!HostTree.isHostTree(tree)) { /* manual filtering */ }\nreturn (t: Tree) => t.visit(p => { if (!predicate(p)) { t.delete(p.path); } });","handlingStrategy":"type-guard","validationCode":"import { HostTree } from '@angular-devkit/schematics';\nif (!HostTree.isHostTree(tree)) {\n  throw new Error('filter() requires a HostTree');\n}","typeGuard":"function isHostTree(t: Tree): t is HostTree {\n  return HostTree.isHostTree(t);\n}","tryCatchPattern":"try {\n  return applyRules([filter(predicate)], tree);\n} catch (err) {\n  if (err.message.includes('Tree type is not supported')) {\n    // fall back to manual visit/delete filtering\n  }\n}","preventionTips":["Only call filter() on HostTree-based trees.","Prefer manual tree.visit + tree.delete for custom Tree implementations.","Avoid exotic Tree wrappers inside filter pipelines."],"tags":["schematics","tree","type-mismatch"],"backgroundTag":"incompatible-tree-type","analyzedSha":"bb72145f9ab45aee29f523236b3a25cd0813a841","analyzedAt":"2026-08-30T02:47:34.745Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}