Tencent/WeKnora · error · AppError

opensearch: index not found

Error message

opensearch: index not found

What it means

A RangeFunction node was found in the FROM clause — a set-returning function used as a table source, e.g. `FROM generate_series(...)`, `FROM unnest(...)`, or file/network-reading functions. The validator unconditionally blocks these because set-returning functions can invoke arbitrary server-side code (file reads, command execution via extensions) regardless of configuration.

Source

Thrown at internal/application/repository/retriever/opensearch/errors.go:15

// Package opensearch implements the RetrieveEngineRepository interface
// for OpenSearch k-NN native vector search.
package opensearch

import "errors"

// Sentinel errors returned by Repository. The service-layer factory wraps
// these into typed AppError values (2200/2201) — the repository itself
// never imports internal/errors. The boundary is intentional (directional
// dependency).
var (
	// ErrIndexNotFound — alias / underlying index missing. Search and
	// delete-by-query operations return this when the per-dim alias has
	// not been created yet (no Save has been issued for that dim).
	ErrIndexNotFound = errors.New("opensearch: index not found")

	// ErrDimensionMismatch — embedding dimension violates the per-dim
	// invariant (e.g. dim <= 0, dim > 16000, or embeddings within a
	// single batch disagree).
	ErrDimensionMismatch = errors.New("opensearch: embedding dimension mismatch")

	// ErrAuth — cluster returned 401 / 403. Distinguished from ErrTransport
	// so the service layer can map to a clean 4xx instead of 503.
	ErrAuth = errors.New("opensearch: authentication failed")

	// ErrTransport — network / 5xx / opaque cluster error. Classified as
	// transient: ensureReady does NOT persist this in initErr, so the next
	// caller will retry.
	ErrTransport = errors.New("opensearch: transport error")

	// ErrVersionUnsupported — cluster is not OpenSearch, is OS 1.x, or is
	// OS 2.0~2.3 (pre-Lucene-HNSW-GA). probeVersion enforces.
	ErrVersionUnsupported = errors.New("opensearch: cluster version unsupported")

View on GitHub (pinned to 988cbb0330)

Solutions

  1. Replace the function source with a real table: materialize the series/rows into a temp or permanent table outside the validated query and select from it.
  2. For generate_series-style row expansion, do the expansion in application code and pass values as parameters (e.g. `WHERE id = ANY($1)`).
  3. For unnest, pass the array as a parameter and expand client-side, since `SELECT unnest($1::int[])` in the target list is validated by function rules, whereas FROM-range functions are always denied.

Example fix

// before
SELECT * FROM generate_series(1, 10) AS n;

// after
SELECT id FROM my_numbers WHERE id BETWEEN 1 AND 10;
Defensive patterns

Strategy: validation

Validate before calling

var fromFunc = regexp.MustCompile(`(?i)\bfrom\s+[a-z_][a-z0-9_]*\s*\(`)
if fromFunc.MatchString(sql) {
	// reject or rewrite: set-returning functions cannot be a FROM source
}

Try / catch

if err := validator.ValidateQuery(sql); err != nil {
	if strings.Contains(err.Error(), "functions in FROM clause") {
		return fmt.Errorf("materialize function output into a table first: %w", err)
	}
}

Prevention

When it happens

Trigger: Validating `SELECT * FROM generate_series(1,10)`, `SELECT * FROM unnest(ARRAY[1,2])`, `SELECT * FROM read_text('/etc/passwd')`, or a hidden RangeFunction inside an otherwise-allowed FROM subquery.

Common situations: Analytics queries that naturally use generate_series/unnest to expand rows; exploit attempts smuggling functions in FROM; SQL generation code that emits table-valued functions instead of joining real tables.

Related errors


AI-assisted analysis of Tencent/WeKnora@988cbb0330 (2026-09-02). Data as JSON: /api/errors/96c1a42b59511b8d. Report an issue: GitHub.