kataras/iris · warning

not found

Error message

not found

What it means

ErrNotFound is the sentinel error of Context's key-value storage (ctx.Get, ctx.Set, Update, Delete, GetByID in the Context store / Params / memstore). It is returned when the requested key or ID does not exist. The docs recommend errors.Is(err, context.ErrNotFound) since exact equality may break in future versions.

Source

Thrown at context/context.go:1581

// URLParamEscape returns the escaped url query parameter from a request.
func (ctx *Context) URLParamEscape(name string) string {
	return DecodeQuery(ctx.URLParam(name))
}

// ErrNotFound is the type error which API users can make use of
// to check if a `Context` action of a `Handler` is type of Not Found,
// e.g. URL Query Parameters.
// Example:
//
// n, err := context.URLParamInt("url_query_param_name")
//
//	if errors.Is(err, context.ErrNotFound) {
//		// [handle error...]
//	}
//
// Another usage would be `err == context.ErrNotFound`
// HOWEVER prefer use the new `errors.Is` as API details may change in the future.
var ErrNotFound = errors.New("not found")

// URLParamInt returns the url query parameter as int value from a request,
// returns -1 and an error if parse failed or not found.
func (ctx *Context) URLParamInt(name string) (int, error) {
	if v := ctx.URLParam(name); v != "" {
		n, err := strconv.Atoi(v)
		if err != nil {
			return -1, err
		}
		return n, nil
	}

	return -1, ErrNotFound
}

// URLParamIntDefault returns the url query parameter as int value from a request,
// if not found or parse failed then "def" is returned.
func (ctx *Context) URLParamIntDefault(name string, def int) int {

View on GitHub (pinned to 7bedaf55a0)

Solutions

  1. Use errors.Is(err, context.ErrNotFound) to detect the missing-key case and handle it (create default, return 404, etc.).
  2. Verify the key/ID spelling matches exactly what was stored via ctx.Set.
  3. Check middleware/handler ordering so the value is set before it is read.
  4. If the value should persist across requests, use a session or database instead of the per-request context store.

Example fix

// before
v, err := ctx.Get("userID")
userID := v.(int) // panics if not found
// after
v, err := ctx.Get("userID")
if err != nil {
    if errors.Is(err, context.ErrNotFound) {
        ctx.StopWithStatus(iris.StatusNotFound)
        return
    }
    return
}
Defensive patterns

Strategy: try-catch

Validate before calling

// nothing to validate beforehand if you don't control the key lifecycle;
// verify the key was set earlier:
//   ctx.Set("userID", 42)
// then reading with Get must use the exact same key string

Type guard

func hasValue(ctx iris.Context, key string) bool {
    _, err := ctx.Get(key)
    return !errors.Is(err, context.ErrNotFound)
}

Try / catch

v, err := ctx.Get("userID")
if err != nil {
    if errors.Is(err, context.ErrNotFound) { // prefer errors.Is per docs
        ctx.StopWithStatus(iris.StatusNotFound)
        return
    }
    return
}

Prevention

When it happens

Trigger: Calling ctx.Get/GetByID/Update/Delete with a key or ID that was never set, or after it was removed; reading a stored value before the handler/middleware that sets it has run.

Common situations: Middleware ordering mistakes (reading a session/user value before the middleware that stores it); typos in key names; expecting a value across requests when it is only per-request; deleting a key twice.

Related errors


AI-assisted analysis of kataras/iris@7bedaf55a0 (2026-08-30). Data as JSON: /api/errors/474c46d495e27730. Report an issue: GitHub.