angular/angular-cli · error · SchematicsException

Tree type is not supported.

Error message

Tree type is not supported.

What it means

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.

Source

Thrown at packages/angular_devkit/schematics/src/rules/base.ts:80

export function mergeWith(source: Source, strategy: MergeStrategy = MergeStrategy.Default): Rule {
  return (tree, context) => {
    return callSource(source, context).pipe(
      map((sourceTree) => tree.merge(sourceTree, strategy || context.strategy)),
      mapTo(tree),
    );
  };
}

export function noop(): Rule {
  return () => {};
}

export function filter(predicate: FilePredicate<boolean>): Rule {
  return (tree: Tree) => {
    if (HostTree.isHostTree(tree)) {
      return new FilterHostTree(tree, predicate);
    } else {
      throw new SchematicsException('Tree type is not supported.');
    }
  };
}

export function asSource(rule: Rule): Source {
  return (context) => callRule(rule, staticEmpty(), context);
}

export function branchAndMerge(rule: Rule, strategy: MergeStrategy = MergeStrategy.Default): Rule {
  return (tree, context) => {
    return callRule(rule, tree.branch(), context).pipe(
      map((branch) => tree.merge(branch, strategy || context.strategy)),
      mapTo(tree),
    );
  };
}

export function when(predicate: FilePredicate<boolean>, operator: FileOperator): FileOperator {

View on GitHub (pinned to bb72145f9a)

Solutions

  1. Ensure the tree is a HostTree — operate on the underlying host tree instead of a custom Tree.
  2. Replace filter() with manual visit/delete logic that works on any Tree implementation.
  3. If wrapping trees (e.g. in a UnitTestTree), pass the underlying HostTree (tree.branch() or host access).

Example fix

// before
return filter(p => p)(tree as any);
// after
if (!HostTree.isHostTree(tree)) { /* manual filtering */ }
return (t: Tree) => t.visit(p => { if (!predicate(p)) { t.delete(p.path); } });
Defensive patterns

Strategy: type-guard

Validate before calling

import { HostTree } from '@angular-devkit/schematics';
if (!HostTree.isHostTree(tree)) {
  throw new Error('filter() requires a HostTree');
}

Type guard

function isHostTree(t: Tree): t is HostTree {
  return HostTree.isHostTree(t);
}

Try / catch

try {
  return applyRules([filter(predicate)], tree);
} catch (err) {
  if (err.message.includes('Tree type is not supported')) {
    // fall back to manual visit/delete filtering
  }
}

Prevention

When it happens

Trigger: 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).

Common situations: 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.

Related errors


AI-assisted analysis of angular/angular-cli@bb72145f9a (2026-08-30). Data as JSON: /api/errors/7586be0b7db05095. Report an issue: GitHub.