Tencent/WeKnora · error · AppError

2201

2201

Error message

opensearch: embedding dimension mismatch

What it means

A SubLink node — a subquery nested inside an expression such as `WHERE id IN (SELECT ...)`, `EXISTS (...)`, or a scalar subquery in the target list — was found while checkSubqueries is enabled. Subqueries in expressions can smuggle dangerous functions and nested constructs, so the validator rejects them when subquery checking is on.

Source

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

// 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")

	// ErrConfigInvalid — IndexConfig / storeID / sanitizeIndexName guard
	// failed, or the k-NN plugin is missing on one or more cluster nodes.
	ErrConfigInvalid = errors.New("opensearch: invalid index config")

View on GitHub (pinned to 988cbb0330)

Solutions

  1. Rewrite the subquery as a JOIN: `WHERE id IN (SELECT user_id FROM admins)` becomes an INNER JOIN on admins.user_id (deduplicating if needed).
  2. Replace scalar subqueries in the SELECT list with a LEFT JOIN + aggregate, or compute the value beforehand and pass it as a parameter.
  3. Replace EXISTS anti-join patterns with LEFT JOIN ... IS NULL, or with NOT IN / parameters when the subquery result is small and computed client-side.
  4. If subqueries are legitimately needed from a trusted source, disable checkSubqueries in the validator config.

Example fix

// before
SELECT * FROM users WHERE id IN (SELECT user_id FROM admins);

// after
SELECT u.* FROM users u JOIN admins a ON a.user_id = u.id;
Defensive patterns

Strategy: validation

Validate before calling

var subqInExpr = regexp.MustCompile(`(?i)\b(in|exists|not\s+exists)\s*\(\s*select\b`)
if subqInExpr.MatchString(sql) {
	// rewrite as JOIN or precompute the value before validating
}

Try / catch

if err := validator.ValidateQuery(sql); err != nil {
	if err.Error() == "subqueries are not allowed" {
		return fmt.Errorf("use JOINs instead of IN/EXISTS subqueries: %w", err)
	}
}

Prevention

When it happens

Trigger: Validating `SELECT * FROM users WHERE id IN (SELECT user_id FROM admins)`, `SELECT EXISTS (SELECT 1 FROM x) FROM t`, or `(SELECT max(id) FROM t)` as a scalar expression.

Common situations: Common idioms like IN/EXISTS/not-EXISTS correlated filters, scalar lookups in SELECT lists; ORMs that emit subqueries for lazy relations or filtering; queries rewritten to avoid JOINs.

Related errors


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