Bug Report
When an extern fn is called with an invalid reference as an argument, the compiler does not call the function (correct), but still calls the decorator with the function's declared return type (the Reflection.Operation Model) instead of skipping the decorator application or reporting an error gracefully.
This causes an internal compiler crash.
Minimal Repro
main.tsp
import "./test.js";
#suppress "experimental-feature" "testing extern fn crash with invalid ref"
extern fn myFn(target: Reflection.Operation): Reflection.Operation;
extern dec myDec(target: Reflection.Operation, override: Reflection.Operation);
op test(): void;
@@myDec(test, myFn(invalidref));
test.js
// @ts-check
export const $functions = {
"": {
myFn: (context, target) => {
console.log("BUG: myFn was called despite invalid reference argument");
return target;
},
},
};
export const $myDec = (context, target, override) => {
console.log("$myDec called");
console.log(" target:", target?.kind, target?.name);
console.log(" override:", override?.kind, override?.name);
override.parameters.properties;
};
Observed Behavior
$myDec called
target: Operation test
override: Model Operation ← WRONG: should be an Operation, not the type Model
Internal compiler error!
TypeError: Cannot read properties of undefined (reading 'properties')
at $myDec (test.js)
at applyDecoratorToType (checker.ts:8646)
The decorator $myDec is called with override being the Reflection.Operation Model type (kind: "Model", name: "Operation") — the declared return type of myFn — instead of an actual Operation instance.
Expected Behavior
When the function call myFn(invalidref) fails due to an invalid reference:
- The decorator should not be applied (since its argument could not be resolved), OR
- An error diagnostic should be reported and the decorator call skipped
The compiler should never pass the raw return type declaration as a decorator argument.
Stack Trace
TypeError: Cannot read properties of undefined (reading 'properties')
at $myDec (test.js:20:23)
at applyDecoratorToType (checker.ts:8646:12)
at applyDecoratorsToType (checker.ts:7919:26)
at finishType (checker.ts:7903:30)
at finishOperation (checker.ts:2667:14)
Real-world Impact
This is triggered by @@override(test, reorderParameters(abcde, #["b", "a"])) in @azure-tools/typespec-client-generator-core where abcde is a typo/invalid reference. The $override decorator crashes at override.parameters.properties.
Version
TypeSpec compiler v1.12.0
Bug Report
When an
extern fnis called with an invalid reference as an argument, the compiler does not call the function (correct), but still calls the decorator with the function's declared return type (theReflection.OperationModel) instead of skipping the decorator application or reporting an error gracefully.This causes an internal compiler crash.
Minimal Repro
main.tsp
test.js
Observed Behavior
The decorator
$myDecis called withoverridebeing theReflection.OperationModel type (kind: "Model", name: "Operation") — the declared return type ofmyFn— instead of an actualOperationinstance.Expected Behavior
When the function call
myFn(invalidref)fails due to an invalid reference:The compiler should never pass the raw return type declaration as a decorator argument.
Stack Trace
Real-world Impact
This is triggered by
@@override(test, reorderParameters(abcde, #["b", "a"]))in@azure-tools/typespec-client-generator-corewhereabcdeis a typo/invalid reference. The$overridedecorator crashes atoverride.parameters.properties.Version
TypeSpec compiler v1.12.0