The compiler reports E08030 on my discount lookup. What is wrong and how do I fix it?

← Debugging and Troubleshooting · Ref: Q993

E08030 means you called an accessor on an Optional, Result or Iterator (get(), ok(), error(), next()) without first proving it holds a value. It is only raised for those types: an ordinary value such as a Float that might be unset can be used directly, and the result is simply unset too.

IN THIS CODE:

lookupDiscount returns an Optional of Float - empty for an unknown product. The failing code calls .get() straight away:

  lookupDiscount()
    -> productCode as String
    <- rtn as Optional of Float: Optional() of Float
    if productCode == "PREMIUM"
      rtn: Optional(0.20)
  basePrice <- 100.0
  discount <- lookupDiscount("PREMIUM")
  finalPrice <- basePrice - (basePrice * discount.get())   // ERROR E08030: not checked before access
  stdout.println($finalPrice)

THE FIX:

Use a declaration guard, which declares the variable AND checks that it is set:

  if discount <- lookupDiscount(productCode)
    finalPrice <- basePrice - (basePrice * discount.get())

The body only runs when the Optional holds a discount, so the get() inside it is safe. 'if discount?' after a separate declaration works the same way.

ALTERNATIVELY:

Ask the Optional for a default, so there is nothing to check:

  rate <- lookupDiscount(productCode).getOrDefault(0.0)
  finalPrice <- basePrice - (basePrice * rate)

This uses 0.0 (no discount) when the Optional is empty.

Example

defines module qa.debugging.diagnoseerror

  defines function

    lookupDiscount() as pure
      -> productCode as String
      <- rtn as Optional of Float: Optional() of Float

      premiumCode <- "PREMIUM"
      standardCode <- "STANDARD"

      if productCode == premiumCode
        rtn: Optional(0.20)
      else if productCode == standardCode
        rtn: Optional(0.10)

  defines program

    DiagnoseErrorDemo()
      stdout <- Stdout()

      basePrice <- 100.0

      //Correct: the guard checks the Optional, so get() inside the body is safe
      if discount <- lookupDiscount("PREMIUM")
        finalPrice <- basePrice - (basePrice * discount.get())
        stdout.println(`Discounted price: ${finalPrice}`)

      //Correct: getOrDefault needs no check - an unknown product gets 0.0
      standardDiscount <- lookupDiscount("UNKNOWN").getOrDefault(0.0)
      regularPrice <- basePrice - (basePrice * standardDiscount)
      stdout.println(`Regular price: ${regularPrice}`)

Common mistakes

E08030 — Calling get() on an Optional that has not been checked is rejected. Use a guard 'if v <- expr()' (or 'if v?') before get(), or getOrDefault(). See ek9 -h E08030.

Incorrect:

      discount <- lookupDiscount("PREMIUM")
      finalPrice <- basePrice - (basePrice * discount.get())
      stdout.println(`Discounted price: ${finalPrice}`)

Correct:

      if discount <- lookupDiscount("PREMIUM")
        finalPrice <- basePrice - (basePrice * discount.get())
        stdout.println(`Discounted price: ${finalPrice}`)

E01073 — 'null' does not exist in EK9. Use a guard 'if v <- expr()' to check the Optional, or the ? suffix: 'if discount?'. See ek9 -h E01073.

Incorrect:

      discount <- lookupDiscount("PREMIUM")
      if discount != null
        finalPrice <- basePrice - (basePrice * discount.get())
        stdout.println(`Discounted price: ${finalPrice}`)

Correct:

      if discount <- lookupDiscount("PREMIUM")
        finalPrice <- basePrice - (basePrice * discount.get())
        stdout.println(`Discounted price: ${finalPrice}`)
Other ways to ask this
  • Diagnose this E08030 error in my EK9 code
  • Why is the compiler saying unsafe access on this line?
  • Help me understand and fix E08030 in this code

Coming from another language?

E08030 in EK9 is like calling Optional.get() in Java without isPresent(), or unwrap() in Rust - except EK9 rejects it at compile time instead of throwing at runtime. There is no escape hatch.

Keywords: Optional, E08030, access, fix, guard, unsafe, getOrDefault, diagnose