cloudflare-vectorize by jezweb/claude-skills
npx skills add https://github.com/jezweb/claude-skills --skill cloudflare-vectorizeCloudflare Vectorize 的完整实现指南 - 这是一个全球分布式向量数据库,用于在 Cloudflare Workers 上构建语义搜索、RAG(检索增强生成)和 AI 驱动的应用程序。
状态:生产就绪 ✅ 最后更新:2026-01-21 依赖项:cloudflare-worker-base(用于 Worker 设置),cloudflare-workers-ai(用于嵌入)最新版本:wrangler@4.59.3,@cloudflare/workers-types@4.20260109.0 节省 Token:~70% 预防错误:14 节省开发时间:~4 小时
广告位招租
在这里展示您的产品或服务
触达数万 AI 开发者,精准高效
重要提示:Vectorize V2 于 2024 年 9 月正式发布,带来了重大的破坏性变更。
性能改进:
破坏性的 API 变更:
异步变更 - 所有变更操作现在都是异步的:
// V2: 返回 mutationId
const result = await env.VECTORIZE_INDEX.insert(vectors);
console.log(result.mutationId); // "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
// 向量插入/删除可能需要几秒钟才能反映出来
returnMetadata 参数 - 布尔值 → 字符串枚举:
// ❌ V1(已弃用)
{ returnMetadata: true }
// ✅ V2(必需)
{ returnMetadata: 'all' | 'indexed' | 'none' }
插入前需要元数据索引:
V1 弃用时间线:
wrangler vectorize --deprecated-v1 标志所需的 Wrangler 版本:
// 获取索引信息以检查最后处理的变更
const info = await env.VECTORIZE_INDEX.describe();
console.log(info.mutationId); // 最后变更 ID
console.log(info.processedUpToMutation); // 最后处理的时间戳
# 1. 使用固定的维度和度量创建索引
npx wrangler vectorize create my-index \
--dimensions=768 \
--metric=cosine
# 2. 立即创建元数据索引(在插入向量之前!)
npx wrangler vectorize create-metadata-index my-index \
--property-name=category \
--type=string
npx wrangler vectorize create-metadata-index my-index \
--property-name=timestamp \
--type=number
原因:元数据索引必须在向量插入之前存在。在元数据索引创建之前添加的向量将无法在该属性上进行过滤。
# 维度必须与您的嵌入模型输出匹配:
# - Workers AI @cf/baai/bge-base-en-v1.5: 768 维度
# - OpenAI text-embedding-3-small: 1536 维度
# - OpenAI text-embedding-3-large: 3072 维度
# 度量决定相似度计算:
# - cosine: 最适合归一化嵌入(最常见)
# - euclidean: 向量之间的绝对距离
# - dot-product: 用于非归一化向量
wrangler.jsonc:
{
"name": "my-vectorize-worker",
"main": "src/index.ts",
"compatibility_date": "2025-10-21",
"vectorize": [
{
"binding": "VECTORIZE_INDEX",
"index_name": "my-index"
}
],
"ai": {
"binding": "AI"
}
}
export interface Env {
VECTORIZE_INDEX: VectorizeIndex;
AI: Ai;
}
interface VectorizeVector {
id: string;
values: number[] | Float32Array | Float64Array;
namespace?: string;
metadata?: Record<string, string | number | boolean | string[]>;
}
interface VectorizeMatches {
matches: Array<{
id: string;
score: number;
values?: number[];
metadata?: Record<string, any>;
namespace?: string;
}>;
count: number;
}
Vectorize V2 支持带有范围查询的高级元数据过滤:
// 相等(隐式 $eq)
{ category: "docs" }
// 不等于
{ status: { $ne: "archived" } }
// 在数组中/不在数组中
{ category: { $in: ["docs", "tutorials"] } }
{ category: { $nin: ["deprecated", "draft"] } }
// 范围查询(数字)- V2 新增
{ timestamp: { $gte: 1704067200, $lt: 1735689600 } }
// 范围查询(字符串)- 前缀搜索
{ url: { $gte: "/docs/workers", $lt: "/docs/workersz" } }
// 使用点表示法的嵌套元数据
{ "author.id": "user123" }
// 多个条件(隐式 AND)
{ category: "docs", language: "en", "metadata.published": true }
低基数(适合 $eq 过滤器):
// 少量唯一值 - 高效过滤
metadata: {
category: "docs", // ~10 个类别
language: "en", // ~5 种语言
published: true // 2 个值(布尔值)
}
高基数(避免在范围查询中使用):
// 许多唯一值 - 避免大范围扫描
metadata: {
user_id: "uuid-v4...", // 数百万个唯一值
timestamp_ms: 1704067200123 // 改用秒
}
当前限制:每个向量 1536 个维度 来源:GitHub Issue #8729
支持的嵌入模型:
@cf/baai/bge-base-en-v1.5:768 维度 ✅text-embedding-3-small:1536 维度 ✅text-embedding-3-large:3072 维度 ❌(需要降维)不支持的模型(>1536 维度):
nomic-embed-code:3584 维度Qodo-Embed-1-7B:>1536 维度解决方法:使用降维技术(例如 PCA)将嵌入压缩到 1536 或更少的维度,但这可能会降低语义质量。
功能请求:更高维度的支持正在考虑中。如果这阻碍了您的用例,请使用限制增加请求表。
// ❌ 无效的元数据键
metadata: {
"": "value", // 空键
"user.name": "John", // 包含点(保留用于嵌套)
"$admin": true, // 以 $ 开头
"key\"with\"quotes": 1 // 包含引号
}
// ✅ 有效的元数据键
metadata: {
"user_name": "John",
"isAdmin": true,
"nested": { "allowed": true } // 在过滤器中以 "nested.allowed" 访问
}
关键:使用 5000 个向量的批次大小以获得最佳性能。
性能数据:
为什么是 5000?
最佳模式:
const BATCH_SIZE = 5000;
async function insertVectors(vectors: VectorizeVector[]) {
for (let i = 0; i < vectors.length; i += BATCH_SIZE) {
const batch = vectors.slice(i, i + BATCH_SIZE);
const result = await env.VECTORIZE.insert(batch);
console.log(`Inserted batch ${i / BATCH_SIZE + 1}, mutationId: ${result.mutationId}`);
// 可选:速率限制延迟
if (i + BATCH_SIZE < vectors.length) {
await new Promise(resolve => setTimeout(resolve, 100));
}
}
}
来源:
Vectorize 默认使用近似最近邻(ANN)搜索,与精确搜索相比,精度约为 80%。
默认模式:近似评分(约 80% 精度)
高精度模式:接近 100% 精度
returnValues: true 启用权衡示例:
// 快速,约 80% 精度,topK 最多 100
const results = await env.VECTORIZE.query(embedding, {
topK: 50,
returnValues: false // 默认
});
// 较慢,约 100% 精度,topK 最多 20
const preciseResults = await env.VECTORIZE.query(embedding, {
topK: 10,
returnValues: true // 高精度评分
});
何时使用高精度:
问题:对现有向量的过滤不起作用
解决方案:删除并重新插入向量 或 在插入之前创建元数据索引
问题:"向量维度与索引配置不匹配"
解决方案:确保嵌入模型输出与索引维度匹配:
- Workers AI bge-base: 768
- OpenAI small: 1536
- OpenAI large: 3072
问题:"无效的元数据键"
解决方案:键不能:
- 为空
- 包含 .(点)
- 包含 "(引号)
- 以 $(美元符号)开头
问题:"过滤器超过 2048 字节"
解决方案:简化过滤器或拆分为多个查询
问题:查询缓慢或精度降低
解决方案:对范围查询使用低基数字段,或对时间戳使用秒而不是毫秒
问题:更新未反映在索引中
解决方案:使用 upsert() 覆盖现有向量,而不是 insert()
问题:"VECTORIZE_INDEX 未定义"
解决方案:将 [[vectorize]] 绑定添加到 wrangler.jsonc
问题:不清楚何时使用命名空间与元数据过滤
解决方案:
- 命名空间:分区键,在元数据过滤器之前应用
- 元数据:命名空间内灵活的键值过滤
问题:插入的向量不能立即查询
解决方案:V2 变更是异步的 - 向量可能需要几秒钟才能反映出来
- 使用 mutationId 跟踪变更状态
- 检查 env.VECTORIZE_INDEX.describe() 中的 processedUpToMutation 时间戳
问题:"returnMetadata 必须是 'all'、'indexed' 或 'none'"
解决方案:V2 将 returnMetadata 从布尔值更改为字符串枚举:
- ❌ V1: { returnMetadata: true }
- ✅ V2: { returnMetadata: 'all' }
错误:wrangler vectorize list --json 输出以日志消息开头,破坏了 JSON 解析 来源:GitHub Issue #11011
受影响的命令:
wrangler vectorize list --jsonwrangler vectorize list-metadata-index --json问题:
$ wrangler vectorize list --json
📋 Listing Vectorize indexes...
[
{ "created_on": "2025-10-18T13:28:30.259277Z", ... }
]
日志消息使输出成为无效 JSON,破坏了通过管道传输到 jq 或其他工具。
解决方案:在解析前删除第一行:
# 使用 tail
wrangler vectorize list --json | tail -n +2 | jq '.'
# 使用 sed
wrangler vectorize list --json | sed '1d' | jq '.'
错误:wrangler types 生成不完整的 VectorizeVectorMetadataFilterOp 类型 来源:GitHub Issue #10092 状态:OPEN(内部跟踪为 VS-461)
问题:生成的类型仅包含 $eq 和 $ne,缺少 V2 运算符:$in、$nin、$lt、$lte、$gt、$gte
影响:当使用有效的 V2 元数据过滤运算符时,TypeScript 显示错误:
const vectorizeRes = env.VECTORIZE.queryById(imgId, {
filter: { gender: { $in: genderFilters } }, // ❌ TS 错误但有效!
topK,
returnMetadata: 'indexed',
});
解决方法:在 wrangler types 修复之前手动覆盖类型:
// 添加到您的类型文件中
type VectorizeMetadataFilter = Record<string,
| string
| number
| boolean
| {
$eq?: string | number | boolean;
$ne?: string | number | boolean;
$in?: (string | number | boolean)[];
$nin?: (string | number | boolean)[];
$lt?: number | string;
$lte?: number | string;
$gt?: number | string;
$gte?: number | string;
}
>;
错误:在 Windows 上运行 wrangler dev 时出现 ENOENT: no such file or directory 来源:GitHub Issue #10383 状态:在 wrangler@4.32.0 中修复
问题:Wrangler 尝试创建名称中包含冒号的外部 worker 文件(在 Windows 上无效):
Error: ENOENT: ... '__WRANGLER_EXTERNAL_VECTORIZE_WORKER:<project>:<binding>'
解决方案:更新到 wrangler@4.32.0 或更高版本:
npm install -g wrangler@latest
错误:topK 超过允许的最大值 来源:Vectorize 限制
问题:最大 topK 值根据查询选项而变化:
| 配置 | 最大 topK |
|---|---|
returnValues: false, returnMetadata: 'none' | 100 |
returnValues: true 或 returnMetadata: 'all' | 20 |
returnMetadata: 'indexed' | 100 |
常见错误:
// ❌ 错误 - 使用 returnValues 时 topK 过高
query(embedding, {
topK: 100, // 超过限制!
returnValues: true // 当为 true 时,最大 topK=20
});
解决方案:
// ✅ 正确 - 遵守条件限制
query(embedding, {
topK: 20,
returnValues: true
});
// ✅ 正确 - 没有返回值时更高的 topK
query(embedding, {
topK: 100,
returnValues: false,
returnMetadata: 'indexed'
});
如果从 V1 迁移到 V2:
npm install -g wrangler@latest)returnMetadata 布尔值 → 字符串枚举('all'、'indexed'、'none')mutationId)V1 弃用:
wrangler vectorize --deprecated-v1问题:将 @cloudflare/vitest-pool-workers 与 Vectorize 或 Workers AI 绑定一起使用会导致运行时失败。 来源:GitHub Issue #7434
错误:wrapped binding module can't be resolved
解决方法:
wrangler-test.jsonc示例:
// wrangler-test.jsonc(无 Vectorize 绑定)
{
"name": "my-worker-test",
"main": "src/index.ts",
"compatibility_date": "2025-10-21"
// 无 vectorize 绑定
}
// vitest.config.ts
import { defineWorkersProject } from '@cloudflare/vitest-pool-workers/config';
export default defineWorkersProject({
test: {
poolOptions: {
workers: {
wrangler: {
configPath: "./wrangler-test.jsonc"
}
}
}
}
});
// 在测试中模拟
import { vi } from 'vitest';
const mockVectorize = {
query: vi.fn().mockResolvedValue({
matches: [
{ id: 'test-1', score: 0.95, metadata: { category: 'docs' } }
],
count: 1
}),
insert: vi.fn().mockResolvedValue({ mutationId: "test-mutation-id" }),
upsert: vi.fn().mockResolvedValue({ mutationId: "test-mutation-id" })
};
// 在测试中使用模拟
test('vector search', async () => {
const env = { VECTORIZE_INDEX: mockVectorize };
// ... 测试逻辑
});
注意:这些提示来自社区讨论和官方博客文章。请根据您的 Vectorize 版本进行验证。
来源:查询最佳实践 置信度:中等 适用于:约 1000 万+ 向量的数据集
对大型数据集进行范围查询($lt、$lte、$gt、$gte)可能会遇到精度降低的问题。
优化策略:
// ❌ 大规模高基数范围
metadata: {
timestamp_ms: 1704067200123
}
filter: { timestamp_ms: { $gte: 1704067200000 } }
// ✅ 分桶为离散值
metadata: {
timestamp_bucket: "2025-01-01-00:00", // 1 小时桶
timestamp_ms: 1704067200123 // 原始值(未索引)
}
filter: {
timestamp_bucket: {
$in: ["2025-01-01-00:00", "2025-01-01-01:00"]
}
}
何时重要:
替代方案:使用分桶值的相等过滤器($eq、$in)。
Vectorize V2 添加了对 list-vectors 操作的支持,用于通过向量 ID 进行分页迭代。
用例:
API:
const result = await env.VECTORIZE_INDEX.list({
limit: 1000, // 每页最多 1000 个
cursor?: string
});
// result.vectors: Array<{ id: string }>
// result.cursor: string | undefined
// result.count: number
// 分页示例
let cursor: string | undefined;
const allVectorIds: string[] = [];
do {
const result = await env.VECTORIZE_INDEX.list({
limit: 1000,
cursor
});
allVectorIds.push(...result.vectors.map(v => v.id));
cursor = result.cursor;
} while (cursor);
限制:
状态:生产就绪 ✅(Vectorize V2 正式发布 - 2024 年 9 月) 最后更新:2026-01-21 节省 Token:~70% 预防错误:14(包括 V2 破坏性变更、测试设置、TypeScript 类型) 变更:添加了 4 个新错误(wrangler --json、TypeScript 类型、Windows 开发、topK 限制)、批量性能最佳实践、查询精度模式、测试设置、关于范围查询和列出向量操作的社区提示。
每周安装
326
仓库
GitHub 星标
652
首次出现
2026 年 1 月 20 日
安全审计
安装于
claude-code269
gemini-cli222
opencode215
cursor206
antigravity200
codex192
Complete implementation guide for Cloudflare Vectorize - a globally distributed vector database for building semantic search, RAG (Retrieval Augmented Generation), and AI-powered applications with Cloudflare Workers.
Status : Production Ready ✅ Last Updated : 2026-01-21 Dependencies : cloudflare-worker-base (for Worker setup), cloudflare-workers-ai (for embeddings) Latest Versions : wrangler@4.59.3, @cloudflare/workers-types@4.20260109.0 Token Savings : ~70% Errors Prevented : 14 Dev Time Saved : ~4 hours
IMPORTANT : Vectorize V2 became GA in September 2024 with significant breaking changes.
Performance Improvements :
Breaking API Changes :
Async Mutations - All mutations now asynchronous:
// V2: Returns mutationId
const result = await env.VECTORIZE_INDEX.insert(vectors);
console.log(result.mutationId); // "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
// Vector inserts/deletes may take a few seconds to be reflected
returnMetadata Parameter - Boolean → String enum:
// ❌ V1 (deprecated)
{ returnMetadata: true }
// ✅ V2 (required)
{ returnMetadata: 'all' | 'indexed' | 'none' }
Metadata Indexes Required Before Insert :
V1 Deprecation Timeline :
wrangler vectorize --deprecated-v1 flag for V1 operationsWrangler Version Required :
// Get index info to check last mutation processed
const info = await env.VECTORIZE_INDEX.describe();
console.log(info.mutationId); // Last mutation ID
console.log(info.processedUpToMutation); // Last processed timestamp
# 1. Create the index with FIXED dimensions and metric
npx wrangler vectorize create my-index \
--dimensions=768 \
--metric=cosine
# 2. Create metadata indexes IMMEDIATELY (before inserting vectors!)
npx wrangler vectorize create-metadata-index my-index \
--property-name=category \
--type=string
npx wrangler vectorize create-metadata-index my-index \
--property-name=timestamp \
--type=number
Why : Metadata indexes MUST exist before vectors are inserted. Vectors added before a metadata index was created won't be filterable on that property.
# Dimensions MUST match your embedding model output:
# - Workers AI @cf/baai/bge-base-en-v1.5: 768 dimensions
# - OpenAI text-embedding-3-small: 1536 dimensions
# - OpenAI text-embedding-3-large: 3072 dimensions
# Metrics determine similarity calculation:
# - cosine: Best for normalized embeddings (most common)
# - euclidean: Absolute distance between vectors
# - dot-product: For non-normalized vectors
wrangler.jsonc :
{
"name": "my-vectorize-worker",
"main": "src/index.ts",
"compatibility_date": "2025-10-21",
"vectorize": [
{
"binding": "VECTORIZE_INDEX",
"index_name": "my-index"
}
],
"ai": {
"binding": "AI"
}
}
export interface Env {
VECTORIZE_INDEX: VectorizeIndex;
AI: Ai;
}
interface VectorizeVector {
id: string;
values: number[] | Float32Array | Float64Array;
namespace?: string;
metadata?: Record<string, string | number | boolean | string[]>;
}
interface VectorizeMatches {
matches: Array<{
id: string;
score: number;
values?: number[];
metadata?: Record<string, any>;
namespace?: string;
}>;
count: number;
}
Vectorize V2 supports advanced metadata filtering with range queries:
// Equality (implicit $eq)
{ category: "docs" }
// Not equals
{ status: { $ne: "archived" } }
// In/Not in arrays
{ category: { $in: ["docs", "tutorials"] } }
{ category: { $nin: ["deprecated", "draft"] } }
// Range queries (numbers) - NEW in V2
{ timestamp: { $gte: 1704067200, $lt: 1735689600 } }
// Range queries (strings) - prefix searching
{ url: { $gte: "/docs/workers", $lt: "/docs/workersz" } }
// Nested metadata with dot notation
{ "author.id": "user123" }
// Multiple conditions (implicit AND)
{ category: "docs", language: "en", "metadata.published": true }
Low Cardinality (Good for $eq filters) :
// Few unique values - efficient filtering
metadata: {
category: "docs", // ~10 categories
language: "en", // ~5 languages
published: true // 2 values (boolean)
}
High Cardinality (Avoid in range queries) :
// Many unique values - avoid large range scans
metadata: {
user_id: "uuid-v4...", // Millions of unique values
timestamp_ms: 1704067200123 // Use seconds instead
}
Current Limit : 1536 dimensions per vector Source : GitHub Issue #8729
Supported Embedding Models :
@cf/baai/bge-base-en-v1.5: 768 dimensions ✅text-embedding-3-small: 1536 dimensions ✅text-embedding-3-large: 3072 dimensions ❌ (requires dimension reduction)Unsupported Models (>1536 dimensions):
nomic-embed-code: 3584 dimensionsQodo-Embed-1-7B: >1536 dimensionsWorkaround : Use dimensionality reduction (e.g., PCA) to compress embeddings to 1536 or fewer dimensions, though this may reduce semantic quality.
Feature Request : Higher dimension support is under consideration. Use Limit Increase Request Form if this blocks your use case.
// ❌ INVALID metadata keys
metadata: {
"": "value", // Empty key
"user.name": "John", // Contains dot (reserved for nesting)
"$admin": true, // Starts with $
"key\"with\"quotes": 1 // Contains quotes
}
// ✅ VALID metadata keys
metadata: {
"user_name": "John",
"isAdmin": true,
"nested": { "allowed": true } // Access as "nested.allowed" in filters
}
Critical : Use batch size of 5000 vectors for optimal performance.
Performance Data :
Why 5000?
Optimal Pattern :
const BATCH_SIZE = 5000;
async function insertVectors(vectors: VectorizeVector[]) {
for (let i = 0; i < vectors.length; i += BATCH_SIZE) {
const batch = vectors.slice(i, i + BATCH_SIZE);
const result = await env.VECTORIZE.insert(batch);
console.log(`Inserted batch ${i / BATCH_SIZE + 1}, mutationId: ${result.mutationId}`);
// Optional: Rate limiting delay
if (i + BATCH_SIZE < vectors.length) {
await new Promise(resolve => setTimeout(resolve, 100));
}
}
}
Sources :
Vectorize uses approximate nearest neighbor (ANN) search by default with ~80% accuracy compared to exact search.
Default Mode : Approximate scoring (~80% accuracy)
High-Precision Mode : Near 100% accuracy
returnValues: trueTrade-off Example :
// Fast, ~80% accuracy, topK up to 100
const results = await env.VECTORIZE.query(embedding, {
topK: 50,
returnValues: false // Default
});
// Slower, ~100% accuracy, topK max 20
const preciseResults = await env.VECTORIZE.query(embedding, {
topK: 10,
returnValues: true // High-precision scoring
});
When to Use High-Precision :
Source : Cloudflare Blog - Building Vectorize
Problem: Filtering doesn't work on existing vectors
Solution: Delete and re-insert vectors OR create metadata indexes BEFORE inserting
Problem: "Vector dimensions do not match index configuration"
Solution: Ensure embedding model output matches index dimensions:
- Workers AI bge-base: 768
- OpenAI small: 1536
- OpenAI large: 3072
Problem: "Invalid metadata key"
Solution: Keys cannot:
- Be empty
- Contain . (dot)
- Contain " (quote)
- Start with $ (dollar sign)
Problem: "Filter exceeds 2048 bytes"
Solution: Simplify filter or split into multiple queries
Problem: Slow queries or reduced accuracy
Solution: Use lower cardinality fields for range queries, or use seconds instead of milliseconds for timestamps
Problem: Updates not reflecting in index
Solution: Use upsert() to overwrite existing vectors, not insert()
Problem: "VECTORIZE_INDEX is not defined"
Solution: Add [[vectorize]] binding to wrangler.jsonc
Problem: Unclear when to use namespace vs metadata filtering
Solution:
- Namespace: Partition key, applied BEFORE metadata filters
- Metadata: Flexible key-value filtering within namespace
Problem: Inserted vectors not immediately queryable
Solution: V2 mutations are asynchronous - vectors may take a few seconds to be reflected
- Use mutationId to track mutation status
- Check env.VECTORIZE_INDEX.describe() for processedUpToMutation timestamp
Problem: "returnMetadata must be 'all', 'indexed', or 'none'"
Solution: V2 changed returnMetadata from boolean to string enum:
- ❌ V1: { returnMetadata: true }
- ✅ V2: { returnMetadata: 'all' }
Error : wrangler vectorize list --json output starts with log message, breaking JSON parsing Source : GitHub Issue #11011
Affected Commands :
wrangler vectorize list --jsonwrangler vectorize list-metadata-index --jsonProblem :
$ wrangler vectorize list --json
📋 Listing Vectorize indexes...
[
{ "created_on": "2025-10-18T13:28:30.259277Z", ... }
]
The log message makes output invalid JSON, breaking piping to jq or other tools.
Solution : Strip first line before parsing:
# Using tail
wrangler vectorize list --json | tail -n +2 | jq '.'
# Using sed
wrangler vectorize list --json | sed '1d' | jq '.'
Error : wrangler types generates incomplete VectorizeVectorMetadataFilterOp type Source : GitHub Issue #10092 Status : OPEN (tracked internally as VS-461)
Problem : Generated type only includes $eq and $ne, missing V2 operators: $in, $nin, $lt, $lte, $gt, $gte
Impact : TypeScript shows false errors when using valid V2 metadata filter operators:
const vectorizeRes = env.VECTORIZE.queryById(imgId, {
filter: { gender: { $in: genderFilters } }, // ❌ TS error but works!
topK,
returnMetadata: 'indexed',
});
Workaround : Manual type override until wrangler types is fixed:
// Add to your types file
type VectorizeMetadataFilter = Record<string,
| string
| number
| boolean
| {
$eq?: string | number | boolean;
$ne?: string | number | boolean;
$in?: (string | number | boolean)[];
$nin?: (string | number | boolean)[];
$lt?: number | string;
$lte?: number | string;
$gt?: number | string;
$gte?: number | string;
}
>;
Error : ENOENT: no such file or directory when running wrangler dev on Windows Source : GitHub Issue #10383 Status : FIXED in wrangler@4.32.0
Problem : Wrangler attempted to create external worker files with colons in the name (invalid on Windows):
Error: ENOENT: ... '__WRANGLER_EXTERNAL_VECTORIZE_WORKER:<project>:<binding>'
Solution : Update to wrangler@4.32.0 or later:
npm install -g wrangler@latest
Error : topK exceeds maximum allowed value Source : Vectorize Limits
Problem : Maximum topK value changes based on query options:
| Configuration | Max topK |
|---|---|
returnValues: false, returnMetadata: 'none' | 100 |
returnValues: true OR returnMetadata: 'all' | 20 |
returnMetadata: 'indexed' | 100 |
Common Error :
// ❌ ERROR - topK too high with returnValues
query(embedding, {
topK: 100, // Exceeds limit!
returnValues: true // Max topK=20 when true
});
Solution :
// ✅ OK - respects conditional limit
query(embedding, {
topK: 20,
returnValues: true
});
// ✅ OK - higher topK without values
query(embedding, {
topK: 100,
returnValues: false,
returnMetadata: 'indexed'
});
If migrating from V1 to V2 :
npm install -g wrangler@latest)returnMetadata boolean → string enum ('all', 'indexed', 'none')mutationId in responses)V1 Deprecation :
wrangler vectorize --deprecated-v1 for V1 operationsIssue : Using @cloudflare/vitest-pool-workers with Vectorize or Workers AI bindings causes runtime failure. Source : GitHub Issue #7434
Error : wrapped binding module can't be resolved
Workaround :
wrangler-test.jsonc without Vectorize/AI bindingsExample :
// wrangler-test.jsonc (no Vectorize binding)
{
"name": "my-worker-test",
"main": "src/index.ts",
"compatibility_date": "2025-10-21"
// No vectorize binding
}
// vitest.config.ts
import { defineWorkersProject } from '@cloudflare/vitest-pool-workers/config';
export default defineWorkersProject({
test: {
poolOptions: {
workers: {
wrangler: {
configPath: "./wrangler-test.jsonc"
}
}
}
}
});
// Mock in tests
import { vi } from 'vitest';
const mockVectorize = {
query: vi.fn().mockResolvedValue({
matches: [
{ id: 'test-1', score: 0.95, metadata: { category: 'docs' } }
],
count: 1
}),
insert: vi.fn().mockResolvedValue({ mutationId: "test-mutation-id" }),
upsert: vi.fn().mockResolvedValue({ mutationId: "test-mutation-id" })
};
// Use mock in tests
test('vector search', async () => {
const env = { VECTORIZE_INDEX: mockVectorize };
// ... test logic
});
Note : These tips come from community discussions and official blog posts. Verify against your Vectorize version.
Source : Query Best Practices Confidence : MEDIUM Applies to : Datasets with ~10M+ vectors
Range queries ($lt, $lte, $gt, $gte) on large datasets may experience reduced accuracy.
Optimization Strategy :
// ❌ High-cardinality range at scale
metadata: {
timestamp_ms: 1704067200123
}
filter: { timestamp_ms: { $gte: 1704067200000 } }
// ✅ Bucketed into discrete values
metadata: {
timestamp_bucket: "2025-01-01-00:00", // 1-hour buckets
timestamp_ms: 1704067200123 // Original (non-indexed)
}
filter: {
timestamp_bucket: {
$in: ["2025-01-01-00:00", "2025-01-01-01:00"]
}
}
When This Matters :
Alternative : Use equality filters ($eq, $in) with bucketed values.
Source : Vectorize Changelog
Vectorize V2 added support for the list-vectors operation for paginated iteration through vector IDs.
Use Cases :
API :
const result = await env.VECTORIZE_INDEX.list({
limit: 1000, // Max 1000 per page
cursor?: string
});
// result.vectors: Array<{ id: string }>
// result.cursor: string | undefined
// result.count: number
// Pagination example
let cursor: string | undefined;
const allVectorIds: string[] = [];
do {
const result = await env.VECTORIZE_INDEX.list({
limit: 1000,
cursor
});
allVectorIds.push(...result.vectors.map(v => v.id));
cursor = result.cursor;
} while (cursor);
Limitations :
Status : Production Ready ✅ (Vectorize V2 GA - September 2024) Last Updated : 2026-01-21 Token Savings : ~70% Errors Prevented : 14 (includes V2 breaking changes, testing setup, TypeScript types) Changes : Added 4 new errors (wrangler --json, TypeScript types, Windows dev, topK limits), batch performance best practices, query accuracy modes, testing setup, community tips on range queries and list-vectors operation.
Weekly Installs
326
Repository
GitHub Stars
652
First Seen
Jan 20, 2026
Security Audits
Gen Agent Trust HubPassSocketPassSnykWarn
Installed on
claude-code269
gemini-cli222
opencode215
cursor206
antigravity200
codex192
React 组合模式指南:Vercel 组件架构最佳实践,提升代码可维护性
105,000 周安装