E12060: constraint reference could not be resolved to a type

Category: E12xxx Security constraints · Reported in phase: PRE_IR_CHECKS · Classification: CONSTRAINT_TYPE_NOT_RESOLVED · All error codes

What went wrong

A 'constrain by' clause references a type name that cannot be resolved. The compiler looked for the named type in the current module scope and its imports but found no match. The constraint reference must resolve to an existing type that extends SecurityGate or CORSPolicy.

Worked examples

The [EXAMPLE] section below shows a service constrained by a name that resolves to nothing ('NonExistentGate'), then by an 'ApiGate' function that is a SecurityGate.

Rationale

Security constraints are not optional decorations. If a constraint reference cannot be resolved, the compiler cannot verify whether the service is properly protected. Rather than silently ignoring an unresolved reference, EK9 treats this as a hard error.

How to fix it

Check the constraint reference for:

  1. Spelling errors in the type name
  2. Missing import for the module containing the type
  3. The type may not have been defined yet

A 'constrain by MissingGate' that names nothing fails; one naming a function that 'is SecurityGate', defined in (or referenced into) the module, is fine.

See also

  • Security posture required: E12050
  • Constraint type must extend SecurityGate or CORSPolicy: E12062
  • Duplicate constraint role: E12064
  • Compilable examples: ek9 -q 1293 (What happens when a constrain by reference cannot be re...) ek9 -q 1294 (What types are valid in a constrain by clause?) ek9 -q 1292 (How does service security posture work with 'open' and ...) ek9 -q 1295 (Why does constrain by X and Y fail when both extend Sec...)

Examples

Every example is compiled by the EK9 compiler: the first fails exactly as captioned, the others fix it.

Fails with E12060: constraint reference could not be resolved to a type

#!ek9
defines module error.e12060.bad

  defines service

    UnresolvedConstraint for :/api constrain by NonExistentGate
      health() as GET for :/status
        <- response as HTTPResponse: () with trait of HTTPResponse
          override status() as pure
            <- rtn as Integer: 200
          override content()
            <- rtn as Bytes: Bytes().withUtf8("ok")
          override contentType() as pure
            <- rtn as String: "text/plain"
          default operator ?

Fixed: Constrain by a SecurityGate that exists

#!ek9
defines module error.e12060.good

  defines function

    ApiGate is SecurityGate
      -> context as HTTPContext
      <- rtn as HTTPContext: context

  defines service

    GatedService for :/api constrain by ApiGate

      health() as GET for :/status
        <- response as HTTPResponse: () with trait of HTTPResponse
          override status() as pure
            <- rtn as Integer: 200
          override content()
            <- rtn as Bytes: Bytes().withUtf8("ok")
          override contentType() as pure
            <- rtn as String: "text/plain"
          default operator ?

Questions and answers

These Q&A entries show E12060 and its fix: