Tencent/WeKnora · error
invalid hit object format
Error message
invalid hit object format
What it means
processSingleHit asserts each element of the hits list is a map[string]interface{}; if a hit is not a JSON object, the code logs a warning and returns this error, aborting the batch. It indicates a malformed element in the Elasticsearch search response's hits array during index copy.
Source
Thrown at internal/application/repository/retriever/elasticsearch/v7/repository.go:1158
}
}
return indexInfoList, nil
}
// processSingleHit processes a single hit and creates index information
func (e *elasticsearchRepository) processSingleHit(ctx context.Context,
hit interface{},
sourceToTargetKBIDMap map[string]string,
sourceToTargetChunkIDMap map[string]string,
targetKnowledgeBaseID string,
) (*typesLocal.IndexInfo, []float32, error) {
log := logger.GetLogger(ctx)
hitMap, ok := hit.(map[string]interface{})
if !ok {
log.Warnf("[ElasticsearchV7] Invalid hit object format")
return nil, nil, fmt.Errorf("invalid hit object format")
}
// Get document source
sourceObj, ok := hitMap["_source"].(map[string]interface{})
if !ok {
log.Warnf("[ElasticsearchV7] Hit missing _source field")
return nil, nil, fmt.Errorf("hit missing _source field")
}
// Get source ChunkID and corresponding target ChunkID
sourceChunkID, ok := sourceObj["chunk_id"].(string)
if !ok {
log.Warnf("[ElasticsearchV7] Source index data missing chunk_id field")
return nil, nil, fmt.Errorf("source index data missing chunk_id field")
}
targetChunkID, ok := sourceToTargetChunkIDMap[sourceChunkID]
if !ok {View on GitHub (pinned to 988cbb0330)
Solutions
- Dump the raw hits array and locate the malformed element to confirm the corruption source
- Ensure decoding uses standard json.Unmarshal into map[string]interface{} without custom transforms
- Verify the source index actually belongs to Elasticsearch and its mapping is intact
- Skip-and-log bad hits instead of failing the whole batch if partial copy is acceptable
Example fix
// before
info, vec, err := processSingleHit(hit)
if err != nil { return err }
// after: skip malformed hits
info, vec, err := processSingleHit(hit)
if err != nil {
log.Warnf("skipping malformed hit: %v", err)
continue
} Defensive patterns
Strategy: type-guard
Validate before calling
null
Type guard
func isHitObject(hit interface{}) (*map[string]interface{}, bool) {
m, ok := hit.(map[string]interface{})
if !ok { return nil, false }
return &m, true
} Try / catch
info, vec, err := processSingleHit(hit)
if err != nil {
log.Warnf("skipping malformed hit: %v", err)
continue // fail-soft per hit instead of aborting the batch
} Prevention
- Decode responses with standard json.Unmarshal into interface{} so hits are maps
- Validate a sample response shape before running full index copies
- Skip-and-log malformed hits in migration jobs rather than failing wholesale
- Alert on any 'invalid hit object format' warnings — they indicate upstream corruption
When it happens
Trigger: processSourceBatch → processSingleHit receives a hit that is not an object — e.g. the hits array contains scalars/arrays, or the previous layer mis-parsed the response so document objects were mangled.
Common situations: Corrupted or non-standard response body; a custom middleware/decoder altering JSON types (e.g. numbers-only elements); hitting a non-ES-compatible service whose hits array has unexpected element types.
Related errors
- invalid search result format
- failed to do bulk: %w
- failed to delete by query: %w
- invalid retriever type: %v
- failed to marshal query embedding: %w
AI-assisted analysis of Tencent/WeKnora@988cbb0330 (2026-09-02).
Data as JSON: /api/errors/2f49a9ab7c7251f1.
Report an issue: GitHub.