This specification is maintained by the AgentRules Working Group. Have enhancements or want to claim maintainership?Submit Specification →
backendcritical PriorityID: meilisearch-1-12-hybrid-search-tenant-tokens

Meilisearch 1.12 Vector Hybrid Search Pagination, Scoped Tenant Tokens, and Typo Invariants

Enforces secure multi-tenant isolation, deterministic semantic search pagination, and strict typo-tolerance boundaries in Meilisearch 1.12+. Mandates cryptographic tenant token generation with embedded tenant filters, offset-to-limit pagination bounds for vector rankers, and disables typo-tolerance on high-entropy unique entity identifiers.

Prohibited Anti-Pattern: Leaking Cross-Tenant Records via Unsigned Search Queries, Typo Corruption on IDs, and Silent Truncation in Vector Hybrid Pagination

Export Ready-to-Drop Configuration

Select format below to copy code or download file directly.

---
description: Meilisearch 1.12 Vector Hybrid Search Pagination, Scoped Tenant Tokens, and Typo Invariants - Enforces secure multi-tenant isolation, deterministic semantic search pagination, and strict typo-tolerance boundaries in Meilisearch 1.12+. Mandates cryptographic tenant token generation with embedded tenant filters, offset-to-limit pagination bounds for vector rankers, and disables typo-tolerance on high-entropy unique entity identifiers.
globs: src/services/search/**/*.{ts,js}, src/lib/meilisearch/**/*.{ts,js}, src/repositories/**/*.{ts,js}, src/api/routes/search/**/*.{ts,js}
alwaysApply: true
verified_by: "agentrules.org"
license: "CC-BY-4.0"
source: "https://agentrules.org/rules/meilisearch-1-12-hybrid-search-tenant-tokens"
---

# Meilisearch 1.12 Vector Hybrid Search Pagination, Scoped Tenant Tokens, and Typo Invariants

> **Severity**: CRITICAL | **Category**: backend
> **Anti-Pattern Warning**: Leaking Cross-Tenant Records via Unsigned Search Queries, Typo Corruption on IDs, and Silent Truncation in Vector Hybrid Pagination

## System Constraints
You are a Principal Software Architect enforcing Meilisearch 1.12 hybrid semantic search standards and cryptographic tenant isolation. You must prohibit un-scoped client-side searches, unbounded vector pagination that trips Meilisearch's maxTotalHits/pagination limit, and typo-tolerance regressions on deterministic identity fields.

## Strict Guidelines
- Engineers MUST ALWAYS generate scoped Tenant Tokens on an authenticated backend server using `generateTenantToken()` with explicit embedded `filter` rules (e.g., `tenant_id = <id>`) and a non-null `expiresAt` UNIX timestamp.
- Engineers MUST NOT allow client applications to query Meilisearch directly using master or default search API keys; all front-end search traffic must use cryptographically signed Tenant Tokens.
- Engineers MUST configure `disableOnAttributes` for `typoTolerance` on high-entropy, unique identifiers such as `sku`, `uuid`, `tenant_id`, and `email` to prevent false-positive matching.
- Services MUST enforce pagination clamping where `offset + limit <= pagination.maxTotalHits` (default 1000) when executing hybrid search (`hybrid: { semanticRatio: number, embedder: string }`), returning a structured exhaustion cursor rather than crashing with an out-of-bounds search exception.
- Services MUST explicitely set `semanticRatio` between 0.0 (pure full-text BM25) and 1.0 (pure vector HNSW) based on the query contract, preventing undefined hybrid weighting behavior across heterogeneous vector distributions.

## Bad vs Good Implementations
### Unscoped Client Search Query vs. Cryptographically Signed Tenant Token with Clamped Hybrid Search

#### Bad Antipattern (AI Common Hallucination)
> **Why it fails**: Using master/write API keys in search routes risks credential exfiltration. Relying on manually passed client filters for tenancy invites bypass vulnerabilities. Unchecked offset + limit allows requests to exceed Meilisearch's pagination.maxTotalHits limit (throwing an API error), and typo-tolerance defaults remain unconfigured.
```typescript
import { MeiliSearch } from 'meilisearch';

const client = new MeiliSearch({ host: 'https://search.corp.internal', apiKey: process.env.MEILISEARCH_MASTER_KEY! });

// ANTI-PATTERN: Direct query with master key, trusting client tenant_id, and unbounded hybrid pagination
export async function searchDocuments(userTenantId: string, query: string, page: number, pageSize: number) {
  const index = client.index('knowledge_base');
  
  // Security risk: Filter can be manipulated or omitted; vector offset can exceed pagination limit
  return await index.search(query, {
    filter: `tenant_id = ${userTenantId}`,
    hybrid: {
      semanticRatio: 0.5,
      embedder: 'default'
    },
    offset: (page - 1) * pageSize,
    limit: pageSize
  });
}
```

#### Production Standard (Correct)
> **Standard**: Derives a scoped tenant token bound strictly to the requester's tenant_id with cryptographic enforcement at the Meilisearch gateway. Guarantees that query pagination strictly satisfies offset + limit <= maxTotalHits to prevent index crashes, and explicitly clamps semanticRatio.
```typescript
import { MeiliSearch } from 'meilisearch';

const adminClient = new MeiliSearch({
  host: 'https://search.corp.internal',
  apiKey: process.env.MEILISEARCH_ADMIN_KEY!
});

const MAX_TOTAL_HITS_LIMIT = 1000;
const TOKEN_EXPIRY_SECONDS = 3600; // 1 hour

export interface ScopedSearchContext {
  tenantId: string;
  userId: string;
}

// PRODUCTION FIX: Generate an isolated Tenant Token locked to tenant_id
export async function issueTenantSearchToken(ctx: ScopedSearchContext): Promise<string> {
  const searchRules = {
    knowledge_base: {
      filter: `tenant_id = "${ctx.tenantId}"`
    }
  };
  
  const expiresAt = new Date(Date.now() + TOKEN_EXPIRY_SECONDS * 1000);
  
  return await adminClient.generateTenantToken(
    process.env.MEILISEARCH_SEARCH_API_KEY_UID!,
    searchRules,
    { expiresAt, apiKey: process.env.MEILISEARCH_SEARCH_API_KEY! }
  );
}

// PRODUCTION FIX: Enforce hybrid pagination boundary clamping
export async function executeHybridSearch(
  tenantScopedClient: MeiliSearch,
  query: string,
  page: number,
  pageSize: number,
  semanticRatio = 0.7
) {
  const index = tenantScopedClient.index('knowledge_base');
  const offset = Math.max(0, (page - 1) * pageSize);
  
  if (offset + pageSize > MAX_TOTAL_HITS_LIMIT) {
    throw new RangeError(`Pagination bounds exceeded: offset + limit must not exceed ${MAX_TOTAL_HITS_LIMIT}`);
  }

  return await index.search(query, {
    hybrid: {
      semanticRatio: Math.min(Math.max(semanticRatio, 0.0), 1.0),
      embedder: 'text-embedding-3-small'
    },
    offset,
    limit: pageSize,
    attributesToRetrieve: ['id', 'title', 'content', 'created_at']
  });
}
```

### Index Settings: Restricting Typo Tolerance on Unique Identifiers

#### Bad Antipattern (AI Common Hallucination)
> **Why it fails**: By default, Meilisearch typo-tolerance matches 1-2 typos on words >= 5 characters. Leaving high-entropy fields (SKUs, IDs, serial numbers) unprotected causes false positives where searching for SKU 'AB-1002' returns 'AB-1003', polluting semantic search relevance.
```typescript
import { MeiliSearch } from 'meilisearch';

const client = new MeiliSearch({ host: 'http://localhost:7700', apiKey: 'masterKey' });

// ANTI-PATTERN: Default typo tolerance applies to exact SKU, tenant_id, and external IDs
export async function configureIndexSettings() {
  const index = client.index('products');
  await index.updateFilterableAttributes(['tenant_id', 'category']);
  // Typo tolerance is left at default on all fields
}
```

#### Production Standard (Correct)
> **Standard**: Explicitly adds 'sku', 'tenant_id', and 'serial_number' to `typoTolerance.disableOnAttributes`, ensuring identifiers require exact character matching while allowing conversational query words to leverage typo tolerance.
```typescript
import { MeiliSearch, Settings } from 'meilisearch';

const client = new MeiliSearch({ host: 'http://localhost:7700', apiKey: process.env.MEILISEARCH_ADMIN_KEY! });

export async function configureSecureIndexSettings() {
  const index = client.index('products');

  const settings: Settings = {
    filterableAttributes: ['tenant_id', 'category', 'status'],
    searchableAttributes: ['title', 'description', 'sku'],
    typoTolerance: {
      enabled: true,
      minWordSizeForTypos: {
        oneTypo: 5,
        twoTypos: 9
      },
      disableOnAttributes: ['sku', 'tenant_id', 'serial_number'],
      disableOnWords: []
    },
    pagination: {
      maxTotalHits: 1000
    }
  };

  const task = await index.updateSettings(settings);
  await client.waitForTask(task.taskUid);
}
```

Architectural Specification & Invariant Rationale

Architectural Invariant Design: Meilisearch 1.12 Vector Hybrid Search Pagination, Scoped Tenant Tokens, and Typo Invariants

Meilisearch 1.12 Vector Hybrid Search Pagination, Scoped Tenant Tokens, and Typo Invariants defines an industrial-grade behavioral standard for backend engineering. Enforces secure multi-tenant isolation, deterministic semantic search pagination, and strict typo-tolerance boundaries in Meilisearch 1.12+. Mandates cryptographic tenant token generation with embedded tenant filters, offset-to-limit pagination bounds for vector rankers, and disables typo-tolerance on high-entropy unique entity identifiers. Modern software architectures require strict adherence to deterministic patterns to guarantee high availability, maintainability, and zero security vulnerabilities.

Framework Paradigm Shift & Drift MechanicsLLMs are trained on millions of open-source repositories containing outdated code, legacy idioms, and unpatched antipatterns. When coding assistants generate implementations for this stack, they default to common statistical tokens: Leaking Cross-Tenant Records via Unsigned Search Queries, Typo Corruption on IDs, and Silent Truncation in Vector Hybrid Pagination Without an explicit system instruction file, developers spend hours debugging silent failures.
Failure Modes & Production Blast Radius

Hazard Analysis: What Breaks Without This Rule

The following failure modes have been cataloged from hundreds of hours of production code reviews where AI assistants produced non-compliant implementations:

Failure ModeAI Symptom (The Anti-Pattern)SeverityProduction Impact & Remedy
AI Hallucination & Deprecation DriftLeaking Cross-Tenant Records via Unsigned Search Queries, Typo Corruption on IDs, and Silent Truncation in Vector Hybrid PaginationCritical
Violating this industrial standard introduces regression bugs, security risks, and unexpected runtime failures in production.
Enforce explicit behavioral system directives across all AI coding assistants in your repository.
Silent Architecture InconsistencyAI assistants produce mixed paradigms across files, creating fragmented codebase conventions.Medium
Increases cognitive load during code reviews and leads to maintenance debt across engineering teams.
Pin project conventions in .cursor/rules, CLAUDE.md, and AGENTS.md so all team agents follow identical guardrails.
Architectural Directives in Detail

Step-by-Step Production Directives

Each rule constraint below is injected into the AI agent's system prompt to establish deterministic boundaries:

1

Engineers MUST ALWAYS generate scoped Tenant Tokens on an authenticated backend server using `generateTenantToken()` with explicit embedded `filter` rules (e.g., `tenant_id = <id>`) and a non-null `expiresAt` UNIX timestamp.

Engineers MUST ALWAYS generate scoped Tenant Tokens on an authenticated backend server using `generateTenantToken()` with explicit embedded `filter` rules (e.g., `tenant_id = <id>`) and a non-null `expiresAt` UNIX timestamp.

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
2

Engineers MUST NOT allow client applications to query Meilisearch directly using master or default search API keys

Engineers MUST NOT allow client applications to query Meilisearch directly using master or default search API keys; all front-end search traffic must use cryptographically signed Tenant Tokens.

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
3

Engineers MUST configure `disableOnAttributes` for `typoTolerance` on high-entropy, unique identifiers such as `sku`, `uuid`, `tenant_id`, and `email` to prevent false-positive matching.

Engineers MUST configure `disableOnAttributes` for `typoTolerance` on high-entropy, unique identifiers such as `sku`, `uuid`, `tenant_id`, and `email` to prevent false-positive matching.

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
4

Services MUST enforce pagination clamping where `offset + limit <= pagination.maxTotalHits` (default 1000) when executing hybrid search (`hybrid

Services MUST enforce pagination clamping where `offset + limit <= pagination.maxTotalHits` (default 1000) when executing hybrid search (`hybrid: { semanticRatio: number, embedder: string }`), returning a structured exhaustion cursor rather than crashing with an out-of-bounds search exception.

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
5

Services MUST explicitely set `semanticRatio` between 0.0 (pure full-text BM25) and 1.0 (pure vector HNSW) based on the query contract, preventing undefined hybrid weighting behavior across heterogeneous vector distributions.

Services MUST explicitely set `semanticRatio` between 0.0 (pure full-text BM25) and 1.0 (pure vector HNSW) based on the query contract, preventing undefined hybrid weighting behavior across heterogeneous vector distributions.

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
Technical Questions & Answers

Frequently Asked Technical Questions

Common questions developers face when configuring AI coding assistants for this stack:

Q:Why is Meilisearch 1.12 Vector Hybrid Search Pagination, Scoped Tenant Tokens, and Typo Invariants critical for AI coding assistants?

Enforces secure multi-tenant isolation, deterministic semantic search pagination, and strict typo-tolerance boundaries in Meilisearch 1.12+. Mandates cryptographic tenant token generation with embedded tenant filters, offset-to-limit pagination bounds for vector rankers, and disables typo-tolerance on high-entropy unique entity identifiers. Without explicit behavioral boundaries, AI coding assistants (Cursor, Claude Code, Windsurf, Codex) rely on training data averages, which frequently produce deprecated, inefficient, or vulnerable code patterns.

Q:How does adopting this rule prevent AI hallucinations?

This rule explicitly declares what the AI must avoid (Leaking Cross-Tenant Records via Unsigned Search Queries, Typo Corruption on IDs, and Silent Truncation in Vector Hybrid Pagination) and prescribes verified positive examples. Grounding the LLM with negative and positive pairs eliminates guesswork.

Q:Which AI coding environments are supported?

This specification is multi-platform compatible: Cursor (.cursor/rules/*.mdc & .cursorrules), Anthropic Claude Code (CLAUDE.md), Windsurf (.windsurfrules), Codex / Cline (AGENTS.md), and GitHub Copilot (.github/copilot-instructions.md).

Q:Can I combine this rule with other technology stacks?

Yes. Use the Interactive Stack Builder or download an Agent Pack to merge this rule with other frontend, backend, database, security, and DevOps rules without syntax collision.

Open Specification · CC BY 4.0·Free for Personal, Team & Commercial In-Repo Use

Citation & Open Source Attribution Guidelines

This specification is licensed under Creative Commons Attribution 4.0 International (CC BY 4.0). You are completely free to adapt and share this rule in your workspace. If citing, including in public AI benchmark datasets, or redistributing, attribution to AgentRules.org is required.

1 Rule in Stack

Meilisearch