ory/hydra · error

ErrKeyCanNotBeTypeAsserted

ErrKeyCanNotBeTypeAsserted

Error message

key could not be type asserted

What it means

ErrKeyCanNotBeTypeAsserted is a sentinel error returned by oryx/mapx helpers (GetString, GetStringSlice, GetTime, GetInt64, GetFloat64, and claim parsers) when the key exists in the map but the stored value's concrete type is not the type the helper expects. It indicates a type mismatch in map[string]any / map[K]any data, not a missing key (that is ErrKeyDoesNotExist). The library throws it so callers can distinguish 'wrong shape' data from absent data.

Source

Thrown at oryx/mapx/type_assert.go:17

// Copyright © 2023 Ory Corp
// SPDX-License-Identifier: Apache-2.0

package mapx

import (
	"encoding/json"
	"errors"
	"math"
	"time"
)

// ErrKeyDoesNotExist is returned when the key does not exist in the map.
var ErrKeyDoesNotExist = errors.New("key is not present in map")

// ErrKeyCanNotBeTypeAsserted is returned when the key can not be type asserted.
var ErrKeyCanNotBeTypeAsserted = errors.New("key could not be type asserted")

// GetString returns a string for a given key in values.
func GetString[K comparable](values map[K]any, key K) (string, error) {
	if v, ok := values[key]; !ok {
		return "", ErrKeyDoesNotExist
	} else if sv, ok := v.(string); !ok {
		return "", ErrKeyCanNotBeTypeAsserted
	} else {
		return sv, nil
	}
}

// GetStringSlice returns a string slice for a given key in values.
func GetStringSlice[K comparable](values map[K]any, key K) ([]string, error) {
	v, ok := values[key]
	if !ok {
		return nil, ErrKeyDoesNotExist
	}

View on GitHub (pinned to 4174065ffb)

Solutions

  1. Check the actual Go type of the map value before calling the typed getter (e.g. switch v := claims["aud"].(type)).
  2. Follow the pattern used in oryx/jwtx/claims.go:57: try GetString first and fall back to GetStringSlice on ErrKeyCanNotBeTypeAsserted to handle both single-value and multi-value claims.
  3. Fix the producer of the map so it stores the expected type for the key.
  4. If only presence matters, check for ErrKeyDoesNotExist separately so a type mismatch is not confused with a missing key.

Example fix

// before
aud, err := mapx.GetString(claims, "aud")
// after
aud, err := mapx.GetString(claims, "aud")
if errors.Is(err, mapx.ErrKeyCanNotBeTypeAsserted) {
    var auds []string
    auds, err = mapx.GetStringSlice(claims, "aud")
    if err == nil {
        result.Audience = auds
    }
}
Defensive patterns

Strategy: type-guard

Validate before calling

v, ok := claims["aud"]
if !ok { /* missing key path */ }
switch v.(type) {
case string, []string:
    // safe to call GetString / GetStringSlice
default:
    // wrong type; handle before calling mapx
}

Type guard

func isStringOrStringSlice(v any) bool {
    switch v.(type) {
    case string, []string:
        return true
    }
    return false
}

Try / catch

aud, err := mapx.GetString(claims, "aud")
if errors.Is(err, mapx.ErrKeyCanNotBeTypeAsserted) {
    auds, err2 := mapx.GetStringSlice(claims, "aud")
    if err2 != nil { /* handle: neither string nor []string */ }
    result.Audience = auds
} else if err != nil {
    // other error (e.g. ErrKeyDoesNotExist)
} else {
    result.Audience = []string{aud}
}

Prevention

When it happens

Trigger: Calling mapx.GetString on a key whose value is not a string (e.g. claims["aud"] holding []string or float64); calling GetTime on a value that is not one of the supported numeric/time types; calling GetInt64 on a non-numeric value; ParseMapInterfaceInterfaceClaims encountering a JWT claim of unexpected type.

Common situations: JWT claims where 'aud' is sometimes a single string and sometimes an array depending on the issuer; decoded JSON numbers arriving as float64 when a string was expected; upstream services or token issuers changing claim types; hand-built config maps with the wrong value type.

Related errors


AI-assisted analysis of ory/hydra@4174065ffb (2026-09-03). Data as JSON: /api/errors/ca6fc16e946b3cd8. Report an issue: GitHub.