Summary
GET /api/graph/{user_id} returns the subject-root node duplicated. For seed-user-demo, subject_root__seed-course-cs101 appears twice in nodes (observed in the raw payload). The Learn knowledge map renders nodes.map(n => <li key={n.id}>...), so the duplicate id produces a React warning:
Encountered two children with the same key, `subject_root__seed-course-cs101`.
Keys should be unique ...
Six such warnings accumulated in the Next dev overlay during the #349 smoke (one per duplicated subject root across the seeded courses).
Where
- Rendering site:
frontend/src/components/KnowledgeGraph2D.tsx:685 (<li key={n.id}>). - Root: the duplicate originates in the graph read — subject-root synthesis or a join fan-out in
backend/routes/graph.py / backend/services/graph_service.py. Confirm by counting nodes[].id in the raw GET /api/graph/{user_id} payload.
Fix direction
Dedup by node id at the source (graph read) so the API never returns two nodes with the same id. A frontend-only key workaround is a band-aid — fix the payload.
Acceptance criteria
Notes
Pre-existing (visible before any streaming). Not caused by #349, but #349's map rendering surfaces it. Reproduce with the seeded seed-user-demo (python -m db.seed_staging).
Filed by Claude Code during the PR #349 e2e-smoke investigation.
Summary
GET /api/graph/{user_id}returns the subject-root node duplicated. Forseed-user-demo,subject_root__seed-course-cs101appears twice innodes(observed in the raw payload). The Learn knowledge map rendersnodes.map(n => <li key={n.id}>...), so the duplicate id produces a React warning:Six such warnings accumulated in the Next dev overlay during the #349 smoke (one per duplicated subject root across the seeded courses).
Where
frontend/src/components/KnowledgeGraph2D.tsx:685(<li key={n.id}>).backend/routes/graph.py/backend/services/graph_service.py. Confirm by countingnodes[].idin the rawGET /api/graph/{user_id}payload.Fix direction
Dedup by node
idat the source (graph read) so the API never returns two nodes with the same id. A frontend-only key workaround is a band-aid — fix the payload.Acceptance criteria
/api/graph/{user_id}returns uniquenodes[].id(assert in a backend test against seed data)./learnfor a course that has a subject root.Notes
Pre-existing (visible before any streaming). Not caused by #349, but #349's map rendering surfaces it. Reproduce with the seeded
seed-user-demo(python -m db.seed_staging).Filed by Claude Code during the PR #349 e2e-smoke investigation.