{"record":{"id":"d06898d57f6ed4c8","repo":"angular/angular-cli","slug":"invalid-source-result-gettypeofresult-value","errorCode":null,"errorMessage":"Invalid source result: ${_getTypeOfResult(value)}.","messagePattern":"Invalid source result: (.+?)\\.","errorType":"exception","errorClass":"InvalidSourceResultException","httpStatus":null,"severity":"error","filePath":"packages/angular_devkit/schematics/src/rules/call.ts","lineNumber":61,"sourceCode":"export class InvalidSourceResultException extends BaseException {\n  constructor(value?: {}) {\n    super(`Invalid source result: ${_getTypeOfResult(value)}.`);\n  }\n}\n\nexport function callSource(source: Source, context: SchematicContext): Observable<Tree> {\n  return defer(async () => {\n    let result: Tree | Observable<Tree> | undefined = source(context);\n\n    if (isObservable(result)) {\n      result = await lastValueFrom(result.pipe(defaultIfEmpty(undefined)));\n    }\n\n    if (result && TreeSymbol in result) {\n      return result;\n    }\n\n    throw new InvalidSourceResultException(result);\n  });\n}\n\nexport function callRule(\n  rule: Rule,\n  input: Tree | Observable<Tree>,\n  context: SchematicContext,\n): Observable<Tree> {\n  if (isObservable(input)) {\n    return input.pipe(mergeMap((inputTree) => callRuleAsync(rule, inputTree, context)));\n  } else {\n    return defer(() => callRuleAsync(rule, input, context));\n  }\n}\n\nasync function callRuleAsync(rule: Rule, tree: Tree, context: SchematicContext): Promise<Tree> {\n  let result = await rule(tree, context);\n","sourceCodeStart":43,"sourceCodeEnd":79,"githubUrl":"https://github.com/angular/angular-cli/blob/bb72145f9ab45aee29f523236b3a25cd0813a841/packages/angular_devkit/schematics/src/rules/call.ts#L43-L79","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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)."],"exampleFix":"// before\nconst mySource: Source = () => chain([rule1, rule2]); // returns a Rule\n// after\nconst mySource: Source = (context) => callRule(chain([rule1, rule2]), empty(), context); // hmm: use empty() Tree\n// or correct Source:\nconst mySource2: Source = () => empty();","handlingStrategy":"type-guard","validationCode":"import { Tree } from '@angular-devkit/schematics';\nfunction ensureTree(v: unknown): Tree {\n  if (!v || !(TreeSymbol in (v as object))) throw new Error('Source must return a Tree');\n  return v as Tree;\n}","typeGuard":"function isTree(v: unknown): v is Tree {\n  return !!v && typeof v === 'object' && TreeSymbol in (v as object);\n}","tryCatchPattern":"try {\n  const tree = await firstValueFrom(callSource(mySource, context));\n} catch (err) {\n  if (err instanceof InvalidSourceResultException) {\n    console.error('Your Source must return a Tree, got:', err.message);\n  }\n}","preventionTips":["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."],"tags":["schematics","source","invalid-return-type"],"backgroundTag":"invalid-return-type","analyzedSha":"bb72145f9ab45aee29f523236b3a25cd0813a841","analyzedAt":"2026-08-30T02:47:34.745Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}