Skip to content
This repository was archived by the owner on Apr 20, 2026. It is now read-only.

Commit 7164c3a

Browse files
rbrennerclaude
andcommitted
fix(mcp,versioning,ingest): PG ROUND type error, hardcoded table names, direct transaction imports
mcp.ts: ROUND(AVG(salience), 4) fails on PG because AVG returns double precision and ROUND(double precision, integer) does not exist in standard PostgreSQL. Use AVG(salience) directly — JS precision is sufficient for stats display. Also fix hardcoded 'waypoints' table name to use waypoints_table variable, consistent with the table variable pattern. versioning.ts, ingest.ts: replace direct transaction singleton import with make_transaction() per-call factory, matching the pattern already used in hsg.ts. Eliminates the latent consistency risk noted in the security review (finding G). Co-Authored-By: Claude <noreply@anthropic.com> AI-Generated: true
1 parent c7d820d commit 7164c3a

3 files changed

Lines changed: 17 additions & 14 deletions

File tree

packages/openmemory-js/src/ai/mcp.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import {
1111
delete_memory,
1212
sector_configs,
1313
} from "../memory/hsg";
14-
import { q, all_async, memories_table, vector_store } from "../core/db";
14+
import { q, all_async, memories_table, waypoints_table, vector_store } from "../core/db";
1515
import { getEmbeddingInfo } from "../memory/embed";
1616
import { j, p } from "../utils";
1717
import type { sector_type, mem_row, rpc_err_code } from "../core/types";
@@ -657,7 +657,7 @@ export const create_mcp_srv = () => {
657657
params,
658658
);
659659
const sector_rows = await all_async(
660-
`SELECT primary_sector, COUNT(*) as count, ROUND(AVG(salience), 4) as avg_salience FROM ${memories_table} ${where} GROUP BY primary_sector`,
660+
`SELECT primary_sector, COUNT(*) as count, AVG(salience) as avg_salience FROM ${memories_table} ${where} GROUP BY primary_sector`,
661661
params,
662662
);
663663
const [dedup_row] = await all_async(
@@ -670,7 +670,7 @@ export const create_mcp_srv = () => {
670670
[...params, seven_days_ago],
671671
);
672672
const [orphan_row] = await all_async(
673-
`SELECT COUNT(*) as orphans FROM ${memories_table} m ${where ? where + ' AND' : 'WHERE'} NOT EXISTS (SELECT 1 FROM waypoints w WHERE w.src_id = m.id OR w.dst_id = m.id)`,
673+
`SELECT COUNT(*) as orphans FROM ${memories_table} m ${where ? where + ' AND' : 'WHERE'} NOT EXISTS (SELECT 1 FROM ${waypoints_table} w WHERE w.src_id = m.id OR w.dst_id = m.id)`,
674674
params,
675675
);
676676

packages/openmemory-js/src/core/versioning.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* - Version retrieval and comparison
88
*/
99

10-
import { run_async, all_async, get_async, q, transaction } from "./db";
10+
import { run_async, all_async, get_async, q, make_transaction } from "./db";
1111
import { env } from "./cfg";
1212
import { rid, now, j } from "../utils";
1313

@@ -330,7 +330,8 @@ export async function restore_version(
330330

331331
// Update the memory with restored content
332332
const new_version = current.version + 1;
333-
await transaction.begin();
333+
const txn = make_transaction();
334+
await txn.begin();
334335
try {
335336
await q.upd_mem_with_sector.run(
336337
version.content,
@@ -340,7 +341,7 @@ export async function restore_version(
340341
now(),
341342
memory_id
342343
);
343-
await transaction.commit();
344+
await txn.commit();
344345

345346
// Save the restored state as well
346347
await save_version(
@@ -356,7 +357,7 @@ export async function restore_version(
356357

357358
return { success: true, new_version };
358359
} catch (e) {
359-
await transaction.rollback();
360+
await txn.rollback();
360361
throw e;
361362
}
362363
}

packages/openmemory-js/src/ops/ingest.ts

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { add_hsg_memory } from "../memory/hsg";
2-
import { q, transaction } from "../core/db";
2+
import { q, make_transaction } from "../core/db";
33
import { rid, now, j } from "../utils";
44
import { extractText, ExtractionResult } from "./extract";
55
import { enrichDocumentMetadata, parse_frontmatter, split_by_sections } from "./document_metadata";
@@ -46,7 +46,8 @@ const mkRoot = async (
4646
const cnt = `[Document: ${ex.metadata.content_type.toUpperCase()}]\n\n${sum}\n\n[Full content split across ${Math.ceil(txt.length / SEC)} sections]`;
4747
const id = rid(),
4848
ts = now();
49-
await transaction.begin();
49+
const txn = make_transaction();
50+
await txn.begin();
5051
try {
5152
await q.ins_mem.run(
5253
id,
@@ -69,11 +70,11 @@ const mkRoot = async (
6970
user_id || "anonymous",
7071
null,
7172
);
72-
await transaction.commit();
73+
await txn.commit();
7374
return id;
7475
} catch (e) {
7576
console.error("[ERROR] Root failed:", e);
76-
await transaction.rollback();
77+
await txn.rollback();
7778
throw e;
7879
}
7980
};
@@ -108,15 +109,16 @@ const link = async (
108109
user_id?: string | null,
109110
) => {
110111
const ts = now();
111-
await transaction.begin();
112+
const txn = make_transaction();
113+
await txn.begin();
112114
try {
113115
await q.ins_waypoint.run(rid, cid, user_id || "anonymous", 1.0, ts, ts);
114-
await transaction.commit();
116+
await txn.commit();
115117
console.log(
116118
`[INGEST] Linked: ${rid.slice(0, 8)} -> ${cid.slice(0, 8)} (section ${idx})`,
117119
);
118120
} catch (e) {
119-
await transaction.rollback();
121+
await txn.rollback();
120122
console.error(`[INGEST] Link failed for section ${idx}:`, e);
121123
throw e;
122124
}

0 commit comments

Comments
 (0)