tobi/qmd · error · Error
Collection '${newName}' already exists
Error message
Collection '${newName}' already exists What it means
renameStoreCollection() refuses to rename a collection to a name that already exists in the store_collections table, to avoid a name collision (which would otherwise break unique lookups).
Source
Thrown at src/store.ts:1380
collection.path,
collection.pattern || '**/*.md',
collection.ignore ? JSON.stringify(collection.ignore) : null,
collection.includeByDefault === false ? 0 : 1,
collection.update || null,
collection.context ? JSON.stringify(collection.context) : null,
);
}
export function deleteStoreCollection(db: Database, name: string): boolean {
const result = db.prepare(`DELETE FROM store_collections WHERE name = ?`).run(name);
return result.changes > 0;
}
export function renameStoreCollection(db: Database, oldName: string, newName: string): boolean {
// Check target doesn't exist
const existing = db.prepare(`SELECT name FROM store_collections WHERE name = ?`).get(newName) as { name: string } | null | undefined;
if (existing != null) {
throw new Error(`Collection '${newName}' already exists`);
}
const result = db.prepare(`UPDATE store_collections SET name = ? WHERE name = ?`).run(newName, oldName);
return result.changes > 0;
}
export function updateStoreContext(db: Database, collectionName: string, path: string, text: string): boolean {
const row = db.prepare(`SELECT context FROM store_collections WHERE name = ?`).get(collectionName) as { context: string | null } | null | undefined;
if (row == null) return false;
const ctxMap: ContextMap = row.context ? JSON.parse(row.context) : {};
ctxMap[path] = text;
db.prepare(`UPDATE store_collections SET context = ? WHERE name = ?`).run(JSON.stringify(ctxMap), collectionName);
return true;
}
export function removeStoreContext(db: Database, collectionName: string, path: string): boolean {
const row = db.prepare(`SELECT context FROM store_collections WHERE name = ?`).get(collectionName) as { context: string | null } | null | undefined;View on GitHub (pinned to dbfd0b4736)
Solutions
- Choose a different target name
- Delete or re-add the existing target collection first if the collision is intended (qmd collection remove <new>)
- Check collection existence with `qmd collection list` before renaming
Example fix
// before
renameStoreCollection(db, 'mynotes', 'notes'); // 'notes' exists
// after
if (!collectionExists(db, 'notes')) renameStoreCollection(db, 'mynotes', 'notes');
else throw new Error('target name taken — pick another'); Defensive patterns
Strategy: validation
Validate before calling
const exists = db.prepare('SELECT 1 FROM store_collections WHERE name=?').get(newName); if (!exists) renameStoreCollection(db, old, newName); Type guard
const isNameFree = (db: Database, n: string) => db.prepare('SELECT 1 FROM store_collections WHERE name=?').get(n) == null; Prevention
- List collections before rename scripts
- Make rename operations idempotent with pre-checks
- Avoid auto-generated target names that can collide
When it happens
Trigger: Calling renameStoreCollection(db, old, new) where a collection named `new` already exists — e.g. `qmd collection rename mynotes notes` when `notes` exists.
Common situations: Re-creating a target name after a previous merge/rename; case-insensitive filesystems hiding an existing name; scripts renaming in a loop that re-run after partial failure.
Related errors
- Collection not found: ${collection}\n${hint}
- Collection '${collection}' has no indexed documents.\nRun 'q
- Collection name is required. Collections must be defined in
- Collection '${newName}' already exists
- Collection '${collectionName}' not found
AI-assisted analysis of tobi/qmd@dbfd0b4736 (2026-08-28).
Data as JSON: /api/errors/b6b982fa7a333334.
Report an issue: GitHub.