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.

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.

Appendix: 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)