gofr-dev/gofr · error

error encoding operation

Error message

error encoding operation

What it means

errEncodingOperation ("error encoding operation") is returned only by Bulk when json.NewEncoder fails to encode one of the operation maps into the bulk request buffer. Since a map[string]any should always be JSON-encodable in principle, this surfaces when an operation contains values Go's json encoder refuses to serialize, such as channels, funcs, complex numbers, or cyclically-referenced values hidden inside nested any fields.

Source

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

)

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
	metrics Metrics
	tracer  trace.Tracer
}

View on GitHub (pinned to 187eb24962)

Solutions

  1. Inspect the operations slice and remove/replace non-JSON-encodable values (func, chan, complex).
  2. If values come from another system, sanitize/convert them to basic JSON types (string, number, bool, nil, slice, map) before passing to Bulk.
  3. Check any custom MarshalJSON implementations on nested values for error paths.

Example fix

// before
op := map[string]any{"index": map[string]any{"_id": id}, "payload": someStructWithChan}
// after
op := map[string]any{"index": map[string]any{"_id": id}, "payload": toPlainJSONValue(someStructWithChan)}
Defensive patterns

Strategy: validation

Validate before calling

func validateEncodable(ops []map[string]any) error {
    for i, op := range ops {
        if _, err := json.Marshal(op); err != nil {
            return fmt.Errorf("operation %d not JSON-encodable: %w", i, err)
        }
    }
    return nil
}

Try / catch

if err := validateEncodable(operations); err != nil {
    return fmt.Errorf("skipping bulk, invalid operations: %w", err)
}
result, err := client.Bulk(ctx, operations)
if err != nil {
    return fmt.Errorf("bulk failed: %w", err)
}

Prevention

When it happens

Trigger: Calling Bulk(ctx, operations) where any entry in the []map[string]any slice contains an unencodable value: a func, chan, complex number, or a value whose MarshalJSON method returns an error.

Common situations: Developers hit this after building bulk operation maps dynamically, e.g. embedding a callback or channel by mistake, or when a custom MarshalJSON implementation panics/errors on certain data.

Understand the failure class

Background: json.Marshal / "failed to marshal" errors in Go: why "unsupported type" happens and how to fix it — this error's family across 22 libraries.

Related errors


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