gofr-dev/gofr · error

operations cannot be empty

Error message

operations cannot be empty

What it means

The claim exists but is not a JSON array ([]any), so index access is impossible; the library wraps errClaimValueNotArray with the key. JWT libraries decode JSON arrays as []any, so a string, single object, or map where an array is expected triggers this.

Source

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

	"time"

	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

View on GitHub (pinned to 187eb24962)

Solutions

  1. Fix the token issuer to emit an array for the claim (e.g. "roles": ["admin"])
  2. If the value is legitimately scalar, change the claim path to the simple key form ("roles") and handle the single value
  3. Pre-validate the token payload shape (assert []any) in tests so mismatches surface before production

Example fix

// before
{"roles": "admin"}
// after
{"roles": ["admin"]}
Defensive patterns

Strategy: type-guard

Validate before calling

raw, ok := claims["roles"]
if !ok { return fmt.Errorf("roles claim missing") }
if _, ok := raw.([]any); !ok {
    return fmt.Errorf("roles claim is not an array")
}

Type guard

func isArrayClaim(claims jwt.MapClaims, key string) bool {
    _, ok := claims[key].([]any)
    return ok
}

Try / catch

v, err := extractClaimValue(claims, "roles[0]")
if errors.Is(err, errClaimValueNotArray) {
    // fall back to scalar handling or reject token
}

Prevention

When it happens

Trigger: Path "roles[0]" but claims["roles"] is a string ("admin"), a single object, or a map — e.g. the issuer emits a scalar role instead of a list, or a custom serializer produced map[string]string.

Common situations: Auth server changed roles from array to single string after a migration; using a JWT library whose claims decode to different Go types; testing with hand-crafted tokens using the wrong shape.

Related errors


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