Skip to content

Commit f37d80b

Browse files
committed
fix(memory): strip extra properties when loading entities from JSONL
When loading entities and relations from JSONL files, the parsed JSON objects included extra properties like `type` (used for discriminating entity vs relation) and any other custom fields. These extra properties leaked into the Entity/Relation objects, causing MCP schema validation errors (-32602 Invalid params) when outputSchema validation is enabled. The fix explicitly extracts only the schema-defined properties (name, entityType, observations for entities; from, to, relationType for relations) instead of casting the entire parsed object. Fixes #3144
1 parent dcb47d2 commit f37d80b

File tree

2 files changed

+48
-2
lines changed

2 files changed

+48
-2
lines changed

src/memory/__tests__/knowledge-graph.test.ts

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -360,6 +360,40 @@ describe('KnowledgeGraphManager', () => {
360360
});
361361
});
362362

363+
describe('loading entities with extra properties', () => {
364+
it('should strip extra properties from entities when loading (issue #3144)', async () => {
365+
// Write JSONL file directly with extra properties (simulating manual edits or legacy data)
366+
const jsonlContent = [
367+
JSON.stringify({ type: "entity", name: "Test", entityType: "test", observations: ["obs1"], custom_id: "xyz-123", extra_field: true }),
368+
JSON.stringify({ type: "relation", from: "Test", to: "Test", relationType: "self", extra_prop: "should be stripped" })
369+
].join('\n');
370+
await fs.writeFile(testFilePath, jsonlContent);
371+
372+
const graph = await manager.readGraph();
373+
374+
// Entities should only have the schema-defined properties
375+
expect(graph.entities).toHaveLength(1);
376+
expect(graph.entities[0]).toEqual({
377+
name: "Test",
378+
entityType: "test",
379+
observations: ["obs1"]
380+
});
381+
expect(graph.entities[0]).not.toHaveProperty('type');
382+
expect(graph.entities[0]).not.toHaveProperty('custom_id');
383+
expect(graph.entities[0]).not.toHaveProperty('extra_field');
384+
385+
// Relations should only have the schema-defined properties
386+
expect(graph.relations).toHaveLength(1);
387+
expect(graph.relations[0]).toEqual({
388+
from: "Test",
389+
to: "Test",
390+
relationType: "self"
391+
});
392+
expect(graph.relations[0]).not.toHaveProperty('type');
393+
expect(graph.relations[0]).not.toHaveProperty('extra_prop');
394+
});
395+
});
396+
363397
describe('file persistence', () => {
364398
it('should persist data across manager instances', async () => {
365399
await manager.createEntities([

src/memory/index.ts

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,8 +74,20 @@ export class KnowledgeGraphManager {
7474
const lines = data.split("\n").filter(line => line.trim() !== "");
7575
return lines.reduce((graph: KnowledgeGraph, line) => {
7676
const item = JSON.parse(line);
77-
if (item.type === "entity") graph.entities.push(item as Entity);
78-
if (item.type === "relation") graph.relations.push(item as Relation);
77+
if (item.type === "entity") {
78+
graph.entities.push({
79+
name: item.name,
80+
entityType: item.entityType,
81+
observations: item.observations
82+
});
83+
}
84+
if (item.type === "relation") {
85+
graph.relations.push({
86+
from: item.from,
87+
to: item.to,
88+
relationType: item.relationType
89+
});
90+
}
7991
return graph;
8092
}, { entities: [], relations: [] });
8193
} catch (error) {

0 commit comments

Comments
 (0)