Skip to content

Compiler crash: decorator called with return type Model when extern fn argument is an invalid reference #10760

@timotheeguerin

Description

@timotheeguerin

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

Metadata

Metadata

Assignees

Labels

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions