E08275: the text given to 'Networking().urlOf()' is known when the program is compiled - an endpoint in the source is configuration hard-coded: read it with 'Networking().urlFromEnv(name)', and derive other URLs from it with 'withPath', 'withPathSegment', 'withQueryParam' or 'resolve'; 'urlOf' is for URL text that arrives while the program runs

Category: E08xxx Pre-IR checks (flow analysis) · Reported in phase: PRE_IR_CHECKS · Classification: URL_TEXT_KNOWN_AT_COMPILE_TIME · All error codes

What went wrong

The text given to 'Networking().urlOf()' is known when the program is compiled. A URL written in the source is an endpoint hard-coded into the program, and EK9 does not allow that: endpoints are configuration, which operations staff change years after the code was written, and an address in the code is also an exposure that a reviewer cannot see from the package. Each of these is E08275:

fromLiteral <- net.urlOf("https://orders.example.com/v1")

fromConstant <- net.urlOf(ordersEndpoint)

base <- "https://orders.example.com"
fromLocal <- net.urlOf(base + "/v1")

The compiler counts text as known when it is a literal, a 'defines constant', a string whose every '${...}' is known, a '+' (or '$', '?:', ternary) of known parts, or a local variable whose declaration and every assignment give it known values. It does not look inside calls, and it never counts a parameter, a property or a loop variable as known - so the check can miss fixed text, but it never refuses text that arrives at run time.

Worked examples

Compilable examples demonstrating this error and the correct fix:

  • ek9 -q 2240 (How do I use a URL in EK9, and why can't I write one in my code?)

Each of these is fine:

  • //The endpoint is configuration: operations set ORDERS_URL, the code never names it.
  • orders <- net.urlFromEnv("ORDERS_URL")
  • items <- orders.withPathSegment("items")
  • //A URL that arrives while the program runs - here, one a user registered.
  • webhook <- net.urlOf(registeredWebhook)

How to fix it

  1. If the URL is an endpoint your program calls, put it in the environment and read it with 'Networking().urlFromEnv("ORDERS_URL")'. A missing or invalid value gives an unset URL.
  2. Build other URLs from that base with 'withPath', 'withPathSegment', 'withQueryParam' or 'resolve'. They keep the base's host, so data cannot move the request somewhere else.
  3. Keep 'urlOf' for URL text that arrives while the program runs - a webhook a user registers, a link in another service's response.

Common causes

  • Porting code that keeps a base URL in a string constant ('BASE_URL = "https://..."')
  • Building a link for a response from a literal host rather than a configured public base URL
  • Moving a literal into a local or a constant first, expecting that to hide it

See also

  • E12010: a gated type used without its capability (Networking needs Networking and EnvVars)

Examples

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

Fails with E08275: the text given to 'Networking().urlOf()' is known when the program is compiled - an endpoint in the source is configuration hard-coded: read it with 'Networking().urlFromEnv(name)', and derive other URLs from it with 'withPath', 'withPathSegment', 'withQueryParam' or 'resolve'; 'urlOf' is for URL text that arrives while the program runs

#!ek9
defines module error.e08275.bad

  defines constant
    ordersEndpoint <- "https://orders.example.com/v1"

  defines function

    hardCodedEndpoints()
      net <- Networking()
      fromLiteral <- net.urlOf("https://orders.example.com/v1")

      fromConstant <- net.urlOf(ordersEndpoint)

      base <- "https://orders.example.com"
      fromLocal <- net.urlOf(base + "/v1")
      require fromLiteral? or fromConstant? or fromLocal?

Fixed: Read the endpoint from the environment and derive from it; give urlOf only text that arrives at run time

#!ek9
defines module error.e08275.good

  defines function

    configuredEndpoints()
      -> registeredWebhook as String
      net <- Networking()
      //The endpoint is configuration: operations set ORDERS_URL, the code never names it.
      orders <- net.urlFromEnv("ORDERS_URL")
      items <- orders.withPathSegment("items")

      //A URL that arrives while the program runs - here, one a user registered.
      webhook <- net.urlOf(registeredWebhook)
      require items? or webhook?

Questions and answers

These Q&A entries show E08275 and its fix: