{"record":{"id":"01d94a7c90184926","repo":"angular/angular","slug":"unsupported-forwardref-fn-call-expected-its-ar","errorCode":null,"errorMessage":"Unsupported `forwardRef(fn)` call, expected its argument to be a function","messagePattern":"Unsupported `forwardRef\\(fn\\)` call, expected its argument to be a function","errorType":"exception","errorClass":"FatalLinkerError","httpStatus":null,"severity":"error","filePath":"packages/compiler-cli/linker/src/file_linker/partial_linkers/util.ts","lineNumber":106,"sourceCode":"  const callee = expr.getCallee();\n  if (callee.getSymbolName() !== 'forwardRef') {\n    throw new FatalLinkerError(\n      callee.expression,\n      'Unsupported expression, expected a `forwardRef()` call or a type reference',\n    );\n  }\n\n  const args = expr.getArguments();\n  if (args.length !== 1) {\n    throw new FatalLinkerError(\n      expr,\n      'Unsupported `forwardRef(fn)` call, expected a single argument',\n    );\n  }\n\n  const wrapperFn = args[0] as AstValue<Function, TExpression>;\n  if (!wrapperFn.isFunction()) {\n    throw new FatalLinkerError(\n      wrapperFn,\n      'Unsupported `forwardRef(fn)` call, expected its argument to be a function',\n    );\n  }\n\n  return createMayBeForwardRefExpression(\n    wrapperFn.getFunctionReturnValue().getOpaque(),\n    ForwardRefHandling.Unwrapped,\n  );\n}\n\nconst STANDALONE_IS_DEFAULT_RANGE = new semver.Range(`>= 19.0.0 || ${PLACEHOLDER_VERSION}`, {\n  includePrerelease: true,\n});\n\nexport function getDefaultStandaloneValue(version: string): boolean {\n  return STANDALONE_IS_DEFAULT_RANGE.test(version);\n}","sourceCodeStart":88,"sourceCodeEnd":124,"githubUrl":"https://github.com/angular/angular/blob/51cb07e98081ab7e4e84a9e0949266a8e19cca84/packages/compiler-cli/linker/src/file_linker/partial_linkers/util.ts#L88-L124","documentation":"Thrown by extractForwardRef() in the Angular partial-declaration linker when a forwardRef(...) call's single argument is not a function. The linker unwraps the forward reference by reading the wrapper function's return value (getFunctionReturnValue()); passing anything else (a string, class reference directly, object literal) makes unwrapping impossible and FatalLinkerError is thrown.","triggerScenarios":"`providedIn: forwardRef('AppModule')` or `providedIn: forwardRef(AppModule)` inside ɵɵngDeclare* metadata — forwardRef requires a lambda that returns the token, not the token itself. Typically hand-written declarations or codegen that 'simplifies' the wrapper away.","commonSituations":"Hand-authored partial declarations and linker test fixtures; code generators emitting the class reference instead of an arrow function; refactoring tools inlining what looks like a redundant wrapper.","solutions":["Always pass a function: forwardRef(() => AppModule)","If you do not need the forward reference, drop the wrapper entirely and use a plain type reference (providedIn: AppModule)","Fix the generator that emits the non-function argument","Restore the library's original published output instead of an edited copy"],"exampleFix":"// before\nprovidedIn: forwardRef(AppModule)\n// after\nprovidedIn: forwardRef(() => AppModule)","handlingStrategy":"type-guard","validationCode":"// Validate that forwardRef's argument is a function before emitting metadata\nif (node.arguments[0]?.type !== 'ArrowFunctionExpression' && node.arguments[0]?.type !== 'FunctionExpression') {\n  throw new Error('forwardRef argument must be a function, e.g. forwardRef(() => Token)');\n}","typeGuard":"function isForwardRefFnArg(node: any): node is {type: 'ArrowFunctionExpression' | 'FunctionExpression'} {\n  return node?.type === 'ArrowFunctionExpression' || node?.type === 'FunctionExpression';\n}","tryCatchPattern":"try {\n  fileLinker.linkPartialDeclaration(fnName, args, scope);\n} catch (e) {\n  if (e instanceof FatalLinkerError && /argument to be a function/.test(e.message)) {\n    throw new Error(`${sourceUrl}: forwardRef must wrap a function returning the token.`);\n  }\n  throw e;\n}","preventionTips":["Write forwardRef(() => Token), never forwardRef(Token) or forwardRef('Token')","Skip the wrapper entirely when the reference is not circular: providedIn: Token","Let the Angular compiler generate these expressions instead of hand-writing them"],"tags":["angular-linker","forwardref","dependency-injection","partial-compilation","build-error"],"backgroundTag":"invalid-argument-type","analyzedSha":"51cb07e98081ab7e4e84a9e0949266a8e19cca84","analyzedAt":"2026-08-22T07:04:54.531Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}