can1357/oh-my-pi · error
import_all: duplicate id ${id} in the imported batch. Dedupl
Error message
import_all: duplicate id ${id} in the imported batch. Deduplicate the input before calling. What it means
`importAll()` in annotations.ts rejects an imported batch that contains the same annotation id more than once. The bulk import API requires the caller to pre-deduplicate; duplicate ids would make the upsert semantics of the batch ambiguous, so it fails fast with this error instead of silently overwriting.
Source
Thrown at packages/mnemopi/src/core/annotations.ts:339
using statement = this.db.prepare(
"SELECT id, memory_id, kind, value, source, confidence, created_at FROM annotations ORDER BY id",
);
const rows = statement.all() as AnnotationRow[];
return rows.map(normalizeRow);
}
importAll(annotations: readonly AnnotationInput[], force = false): AnnotationImportStats {
const stats: AnnotationImportStats = {
inserted: 0,
skipped: 0,
overwritten: 0,
imported_renumbered: 0,
};
const seenIds = new Set<number>();
for (const item of annotations) {
const id = rowId(item.id);
if (id === null) continue;
if (seenIds.has(id)) {
throw new Error(
`import_all: duplicate id ${id} in the imported batch. Deduplicate the input before calling.`,
);
}
seenIds.add(id);
}
transaction(this.db, () => {
using existingStatement = this.db.prepare(
"SELECT id, memory_id, kind, value, source, confidence, created_at FROM annotations",
);
const existingRows = existingStatement.all() as AnnotationRow[];
const existing = new Map<number, StoredAnnotationContent>();
for (const row of existingRows) existing.set(Number(row.id), normalizeRow(row));
using insertWithId = this.db.prepare(
"INSERT INTO annotations (id, memory_id, kind, value, source, confidence, created_at) VALUES (?, ?, ?, ?, ?, ?, ?)",
) as WritableStatement;
using insertWithoutId = this.db.prepare(View on GitHub (pinned to 9690622007)
Solutions
- Deduplicate the input array by id before calling `importAll` (keep the first or the newest item).
- Strip or regenerate ids for items you intend to create fresh so the batch has unique or absent ids.
- If merging exports, drop duplicate ids from the older export.
- Wrap the call in try-catch and on this error, dedupe and retry once.
Example fix
// before
await annotations.importAll([...exportA, ...exportB]);
// after
const seen = new Set<number>();
const deduped = [...exportB, ...exportA].filter(it => {
const id = it.id;
if (id == null) return true;
if (seen.has(id)) return false;
seen.add(id);
return true;
});
await annotations.importAll(deduped); Defensive patterns
Strategy: validation
Validate before calling
const ids = annotations.map(a => a.id).filter(id => id != null);
if (new Set(ids).size !== ids.length) {
throw new Error("Batch contains duplicate ids; dedupe before importAll");
} Type guard
null
Try / catch
try {
await annotations.importAll(batch);
} catch (err) {
if (err instanceof Error && err.message.includes("duplicate id")) {
const seen = new Set();
batch = batch.filter(a => a.id == null || !seen.has(a.id) && seen.add(a.id));
await annotations.importAll(batch);
} else throw err;
} Prevention
- Dedupe merged exports by id before import.
- Regenerate ids for items intended as new rows.
- Keep a single producer of ids in your pipeline.
- Unit-test merge/import helpers with overlapping fixtures.
When it happens
Trigger: Calling `annotations.importAll(items)` where two or more items in `items` carry the same `id` (after `rowId()` normalization). Items with null/unset ids are skipped and do not trigger this.
Common situations: Merging exported annotation files that overlap, re-importing a batch that already includes previously generated ids, concatenating two exports without dedupe, a producer that assigns ids non-uniquely.
Related errors
- Unsupported language '{value}'. Supported: {}
- Unable to infer language from file extension: {}. Specify `l
- Invalid pattern: {err}
- Failed to load tree-sitter language: {err}
- err.to_string() (invalid glob pattern)
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/33acce66c0274f0e.
Report an issue: GitHub.