E12060: constraint reference could not be resolved to a type
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:
- Spelling errors in the type name
- Missing import for the module containing the type
- 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: