angular/angular-cli · error · InvalidSourceResultException
Invalid source result: ${_getTypeOfResult(value)}.
Error message
Invalid source result: ${_getTypeOfResult(value)}. What it means
callSource validates the observable result of a Source: it must be a Tree (marked with the TreeSymbol). If a Source returns anything else (undefined, a rule, a plain object), InvalidSourceResultException is thrown with a type description. It catches Sources implemented incorrectly.
Source
Thrown at packages/angular_devkit/schematics/src/rules/call.ts:61
export class InvalidSourceResultException extends BaseException {
constructor(value?: {}) {
super(`Invalid source result: ${_getTypeOfResult(value)}.`);
}
}
export function callSource(source: Source, context: SchematicContext): Observable<Tree> {
return defer(async () => {
let result: Tree | Observable<Tree> | undefined = source(context);
if (isObservable(result)) {
result = await lastValueFrom(result.pipe(defaultIfEmpty(undefined)));
}
if (result && TreeSymbol in result) {
return result;
}
throw new InvalidSourceResultException(result);
});
}
export function callRule(
rule: Rule,
input: Tree | Observable<Tree>,
context: SchematicContext,
): Observable<Tree> {
if (isObservable(input)) {
return input.pipe(mergeMap((inputTree) => callRuleAsync(rule, inputTree, context)));
} else {
return defer(() => callRuleAsync(rule, input, context));
}
}
async function callRuleAsync(rule: Rule, tree: Tree, context: SchematicContext): Promise<Tree> {
let result = await rule(tree, context);
View on GitHub (pinned to bb72145f9a)
Solutions
- Make the Source return a Tree: e.g. () => MergeStrategy-aware tree, or use callRule(rule, tree, context) inside a rule, not a source.
- If you meant to apply a rule, use callRule or chain in a Rule, not as a Source.
- Check that every code path in the custom source returns a Tree (no bare returns).
Example fix
// before const mySource: Source = () => chain([rule1, rule2]); // returns a Rule // after const mySource: Source = (context) => callRule(chain([rule1, rule2]), empty(), context); // hmm: use empty() Tree // or correct Source: const mySource2: Source = () => empty();
Defensive patterns
Strategy: type-guard
Validate before calling
import { Tree } from '@angular-devkit/schematics';
function ensureTree(v: unknown): Tree {
if (!v || !(TreeSymbol in (v as object))) throw new Error('Source must return a Tree');
return v as Tree;
} Type guard
function isTree(v: unknown): v is Tree {
return !!v && typeof v === 'object' && TreeSymbol in (v as object);
} Try / catch
try {
const tree = await firstValueFrom(callSource(mySource, context));
} catch (err) {
if (err instanceof InvalidSourceResultException) {
console.error('Your Source must return a Tree, got:', err.message);
}
} Prevention
- Sources must return Tree (or Observable<Tree>); apply rules with callRule instead.
- Never end a Source callback without returning a Tree.
- Type custom Sources as Source so TypeScript catches wrong returns.
When it happens
Trigger: A custom Source callback that returns a non-Tree value — e.g. returning the result of callRule, a Rule function, undefined, or a promise/observable of a non-tree — consumed via callSource/apply/mergeWith.
Common situations: Writing a custom source that accidentally returns a Rule instead of a Tree; forgetting to return from the source callback (undefined); mixing up Source and Rule when composing pipelines.
Related errors
- Invalid rule result: ${_getTypeOfResult(value)}.
- schematicName cannot be undefined.
- The "not" keyword is not supported in JSON Schema.
- Could not find (/.angular.json)
- Unknown schematics built-in module '${id}' requested from sc
AI-assisted analysis of angular/angular-cli@bb72145f9a (2026-08-30).
Data as JSON: /api/errors/d06898d57f6ed4c8.
Report an issue: GitHub.