What happens when a constrain by reference cannot be resolved?

← Web Services · Ref: Q1293

When a 'constrain by' clause names a type that does not exist, the compiler emits E12060.

WHAT CAUSES E12060

The constraint reference name cannot be found in the current module scope or imports:

  MyApi :/api constrain by NonExistentGate

The compiler searches for 'NonExistentGate' but finds nothing.

COMMON CAUSES

1. Spelling error in the constraint name
2. Missing import for the module containing the function
3. The function has not been defined yet
4. The function is in a different module without a 'references' declaration

HOW TO FIX

Define a function that extends SecurityGate or CORSPolicy in the same module, or import it:

  defines function
    JwtGate is SecurityGate
      -> context as HTTPContext
      <- rtn as HTTPContext: context

Then reference it:

  MyApi :/api constrain by JwtGate

See Q1292 for security posture overview. See Q1294 for constraint type validation. See Q1295 for duplicate constraint roles.

Example

defines module qa.webdeep.constraintresolution

  defines constant

    jsonType <- "application/json"
    noCache <- "no-cache"
    langEn <- "en"
    okStatus <- 200

  defines function

    <?-
      SecurityGate implementation for JWT authentication.
    -?>
    JwtGate is SecurityGate
      -> context as HTTPContext
      <- rtn as HTTPContext: context

  defines service

    <?-
      Service with a valid, resolvable constraint reference.
      JwtGate is defined in this module so it resolves correctly.
    -?>
    ProtectedApi :/api/protected constrain by JwtGate

      resource() as GET for :/resource
        <- response as HTTPResponse: () with trait HTTPResponse
          override content()
            <- rtn as String: `{"protected": true}`
          override status() as pure
            <- rtn as Integer: okStatus
          override contentType() as pure
            <- rtn as String: jsonType
          override cacheControl() as pure
            <- rtn as String: noCache
          override contentLanguage() as pure
            <- rtn as String: langEn
          default operator ?

  defines application

    ConstraintResolutionApp
      register ProtectedApi()

  defines program

    ConstraintResolutionDemo()
      stdout <- Stdout()
      stdout.println("Constraint type resolution:")
      stdout.println("  JwtGate defined in same module -> resolves OK")
      stdout.println("  'constrain by JwtGate' compiles successfully")
      stdout.println("  Missing or misspelled names trigger E12060")

Common mistakes

E12060 — The 'constrain by' reference must resolve to an existing function; NonExistentGate is undefined, so the constraint type cannot be resolved. See ek9 -h E12060 for details.

Incorrect:

:/api/protected constrain by NonExistentGate

Correct:

:/api/protected constrain by JwtGate
Other ways to ask this
  • What is E12060 constraint type not resolved?
  • Why does the compiler reject my constrain by clause?
  • How do I fix an unresolved security constraint reference?
  • What must I import for constrain by to work?

Coming from another language?

Java: Spring Security bean references are resolved at runtime — a typo causes a NoSuchBeanException at startup. Python: decorator references fail at import time. Go: middleware references are compile-time checked. Rust: type references are compile-time checked. EK9: constraint references are resolved at compile time (Phase 5), so typos and missing imports are caught before deployment.

Keywords: E12060, CORSPolicy, resolve, constrain, service, http, reference, SecurityGate, import