fix: bind memory.list tag filter as a single text[] param (#1)
memory.list built its tag filter with a raw sql template:
sql`${memories.tags} @> ${tags}::text[]`
Drizzle expands a JS array embedded in a sql template into positional
params, so one tag produced `@> ($1)::text[]` (Postgres rejected the
bound string as a malformed array literal) and two tags produced
`@> ($1,$2)::text[]` (a record, hence "cannot cast type record to
text[]"). Switch to arrayContains(memories.tags, tags), which binds the
array as one text[] param via the column's toDriver and preserves the
"require ALL tags" (@>) semantics.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { and, desc, eq, inArray, isNull, or, sql } from "drizzle-orm";
|
||||
import { and, arrayContains, desc, eq, inArray, isNull, or } from "drizzle-orm";
|
||||
import { db } from "@/lib/db/client";
|
||||
import {
|
||||
memories,
|
||||
@@ -465,7 +465,13 @@ const memoryList: ToolDef = {
|
||||
}
|
||||
|
||||
if (parsed.data.tags && parsed.data.tags.length > 0) {
|
||||
where.push(sql`${memories.tags} @> ${parsed.data.tags}::text[]`);
|
||||
// Require ALL listed tags (array containment). Use Drizzle's
|
||||
// arrayContains so the JS array binds as a single text[] param
|
||||
// (via the column's toDriver) rather than being expanded into
|
||||
// positional params — a raw `${tags}::text[]` template expands to
|
||||
// `($1)::text[]` / `($1,$2)::text[]`, which Postgres rejects as a
|
||||
// malformed array literal / record cast.
|
||||
where.push(arrayContains(memories.tags, parsed.data.tags));
|
||||
}
|
||||
|
||||
const rows = await db
|
||||
|
||||
Reference in New Issue
Block a user