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
- Check the actual Go type of the map value before calling the typed getter (e.g. switch v := claims["aud"].(type)).
- 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.
- Fix the producer of the map so it stores the expected type for the key.
- 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
- Always compare with errors.Is against the mapx sentinel errors, never == on wrapped errors.
- Handle string-vs-[]string claim duality (like 'aud') explicitly at parse time.
- Log the actual Go type (%T) of offending values when the error occurs to debug the producer.
- Keep a single claim-parsing helper so type fallbacks are consistent across the codebase.
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
- value is out of range
- failed to set token lifespans due to failed client type asse
- cookiex: cookie could not be decoded
- cookiex: purpose must be non-empty and must not contain a pi
- cookiex: at least one secret is required
AI-assisted analysis of ory/hydra@4174065ffb (2026-09-03).
Data as JSON: /api/errors/ca6fc16e946b3cd8.
Report an issue: GitHub.