gofr-dev/gofr · error

elasticsearch operation error

Error message

elasticsearch operation error

What it means

In extractNestedClaim, each dot-separated segment must resolve to a map (map[string]any or jwt.MapClaims). If the current value is some other type (string, number, array, bool), the library wraps errInvalidClaimStructure with the traversed prefix path. This is a shape error: a mid-path segment is a scalar where a nested object is required.

Source

Thrown at pkg/gofr/datasource/elasticsearch/elasticsearch.go:30

	es "github.com/elastic/go-elasticsearch/v8"
	"github.com/elastic/go-elasticsearch/v8/esapi"
	"go.opentelemetry.io/otel/attribute"
	"go.opentelemetry.io/otel/trace"
)

const (
	statusDown     = "DOWN"
	statusUp       = "UP"
	defaultTimeout = 5 * time.Second
)

var (
	errEmptyIndex        = errors.New("index name cannot be empty")
	errEmptyDocumentID   = errors.New("document ID cannot be empty")
	errEmptyQuery        = errors.New("query cannot be empty")
	errEmptyOperations   = errors.New("operations cannot be empty")
	errHealthCheckFailed = errors.New("elasticsearch health check failed")
	errOperation         = errors.New("elasticsearch operation error")
	errMarshaling        = errors.New("error marshaling data")
	errParsingResponse   = errors.New("error parsing response")
	errResponse          = errors.New("invalid elasticsearch response")
	errEncodingOperation = errors.New("error encoding operation")
)

// Config holds the configuration for connecting to Elasticsearch.
type Config struct {
	Addresses []string
	Username  string
	Password  string
}

// Client represents the Elasticsearch client.
type Client struct {
	config  Config
	client  *es.Client
	logger  Logger

View on GitHub (pinned to 187eb24962)

Solutions

  1. Fix the token issuer so intermediate segments are JSON objects
  2. Adjust the path to match the real structure (e.g. treat a JSON-string claim by decoding it separately rather than traversing it)
  3. Pre-validate token payload shape with a test fixture asserting the nested object structure

Example fix

// before
{"permissions": "read,write"} // path: permissions.role
// after
{"permissions": {"role": "admin"}}
Defensive patterns

Strategy: type-guard

Validate before calling

node, ok := claims["permissions"]
if !ok { return fmt.Errorf("permissions missing") }
if _, ok := node.(map[string]any); !ok {
    return fmt.Errorf("permissions must be a nested object")
}

Type guard

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

Try / catch

v, err := extractClaimValue(claims, "permissions.role")
if errors.Is(err, errInvalidClaimStructure) {
    // token shape invalid: reject with 401 and log prefix
}

Prevention

When it happens

Trigger: Path "permissions.role" where claims["permissions"] is a JSON string or array rather than an object; intermediate segment exists but holds a scalar (e.g. "meta.version.name" where meta.version is "1.2").

Common situations: IdP stores permissions as a JSON-encoded string instead of an object; schema drift after an auth-service refactor; misremembered claim layout in config.

Related errors


AI-assisted analysis of gofr-dev/gofr@187eb24962 (2026-09-01). Data as JSON: /api/errors/585dc6f1d336f206. Report an issue: GitHub.