Tencent/WeKnora · error

failed to marshal query embedding: %w

Error message

failed to marshal query embedding: %w

What it means

VectorRetrieve builds a script_score query using cosineSimilarity against the embedding field; the query embedding must be marshaled to JSON for the script params. If json.Marshal of params.Embedding fails, it returns 'failed to marshal query embedding: %w'. Marshaling fails when Embedding is of an unsupported type (e.g. containing NaN/Inf floats, channels, funcs, or a custom type with a broken MarshalJSON).

Source

Thrown at internal/application/repository/retriever/elasticsearch/v8/repository.go:421

	return nil, err
}

// VectorRetrieve performs vector similarity search using cosine similarity
// Returns a slice of RetrieveResult containing matching documents
func (e *elasticsearchRepository) VectorRetrieve(ctx context.Context,
	params typesLocal.RetrieveParams,
) ([]*typesLocal.RetrieveResult, error) {
	log := logger.GetLogger(ctx)
	log.Infof("[Elasticsearch] Vector retrieval: dim=%d, topK=%d, threshold=%.4f",
		len(params.Embedding), params.TopK, params.Threshold)

	filter := e.getBaseConds(params)

	// Build script scoring query with cosine similarity
	queryVectorJSON, err := json.Marshal(params.Embedding)
	if err != nil {
		log.Errorf("[Elasticsearch] Failed to marshal query vector: %v", err)
		return nil, fmt.Errorf("failed to marshal query embedding: %w", err)
	}

	scoreSource := "cosineSimilarity(params.query_vector, 'embedding')"
	minScore := float32(params.Threshold)
	scriptScore := &types.ScriptScoreQuery{
		Query: types.Query{Bool: &types.BoolQuery{Filter: filter}},
		Script: types.Script{
			Source: &scoreSource,
			Params: map[string]json.RawMessage{
				"query_vector": json.RawMessage(queryVectorJSON),
			},
		},
		MinScore: &minScore,
	}
	// Exclude embedding field from source to reduce response size
	sourceFilter := &types.SourceFilter{
		Excludes: []string{"embedding"},
	}

View on GitHub (pinned to 988cbb0330)

Solutions

  1. Validate the embedding before the call: non-nil, correct length, and all values finite (no NaN/Inf).
  2. Check the actual type of params.Embedding matches what the API expects ([]float32); fix the conversion upstream.
  3. If NaN persists, regenerate the embedding or clamp/replace non-finite values.
  4. Inspect the wrapped marshal error — json.MarshalUnsupportedType tells exactly which value/type failed.

Example fix

// before
params.Embedding = normalize(rawOutput) // may contain NaN
res, err := retriever.VectorRetrieve(ctx, params)
// after
for i, v := range embedding {
	if math.IsNaN(float64(v)) || math.IsInf(float64(v), 0) {
		embedding[i] = 0
	}
}
params.Embedding = embedding
res, err := retriever.VectorRetrieve(ctx, params)
Defensive patterns

Strategy: validation

Validate before calling

func validEmbedding(e []float32, dim int) bool {
	if len(e) != dim { return false }
	for _, v := range e {
		if math.IsNaN(float64(v)) || math.IsInf(float64(v), 0) { return false }
	}
	return true
}
if !validEmbedding(params.Embedding, expectedDim) { return errors.New("invalid query embedding") }

Type guard

func isFloat32Slice(v any) bool {
	_, ok := v.([]float32)
	return ok
}

Prevention

When it happens

Trigger: Calling VectorRetrieve with params.Embedding that is nil-wrapped in a type json.Marshal rejects, contains NaN/+Inf/-Inf float32/float64 values, or has an element type (e.g. []int from a bad conversion) that a custom marshaler chokes on.

Common situations: Embeddings produced by a model returning NaN on degenerate input; downstream code converting []float32 through string/any losing fidelity; vendor SDK change altering the Embedding field type from []float32 to []any.

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 Tencent/WeKnora@988cbb0330 (2026-09-02). Data as JSON: /api/errors/b2768bb28f74655a. Report an issue: GitHub.