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
- Inspect the operations slice and remove/replace non-JSON-encodable values (func, chan, complex).
- If values come from another system, sanitize/convert them to basic JSON types (string, number, bool, nil, slice, map) before passing to Bulk.
- 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
- Build operation maps only from JSON-primitive values; sanitize external input first.
- Add a unit test that marshals representative operations before they reach Bulk.
- Avoid embedding channels/funcs in generic any fields when assembling payloads.
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.