From a0bf4145cac1162ca309568b69d12b5dd1daffec Mon Sep 17 00:00:00 2001 From: Dave MacDonald Date: Tue, 9 Jun 2026 11:44:16 -0700 Subject: [PATCH] fix(sync): skip Python venv/ in the code walker collectSyncableFiles (first-sync walker) and the incremental PRUNE_DIR_NAMES set skipped node_modules but not Python venv/. On a Python repo the walker descended into venv/ (thousands of files); the resulting slug collisions crashed putPage's INSERT ... ON CONFLICT ... RETURNING with "undefined is not an object (evaluating 'row.deleted_at')". Add `venv` alongside node_modules in both the import.ts inline skip and PRUNE_DIR_NAMES. venv is the Python equivalent of node_modules. Co-Authored-By: Claude Opus 4.8 (1M context) --- src/commands/import.ts | 5 ++++- src/core/sync.ts | 5 +++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/commands/import.ts b/src/commands/import.ts index 37d3d3dad..3270f9137 100644 --- a/src/commands/import.ts +++ b/src/commands/import.ts @@ -548,7 +548,10 @@ export function collectSyncableFiles(dir: string, opts: CollectOpts = {}): strin // Same set the legacy walkers honored, surfaced once at the top of // every iteration. if (entry.startsWith('.')) continue; - if (entry === 'node_modules' || entry === 'ops') continue; + // `venv` is the Python equivalent of `node_modules`: a vendored + // dependency tree (often thousands of files) that floods the slug + // namespace and triggers ON CONFLICT collisions on first full sync. + if (entry === 'node_modules' || entry === 'ops' || entry === 'venv') continue; const full = join(d, entry); let stat; diff --git a/src/core/sync.ts b/src/core/sync.ts index 6604343a6..1a753cb4c 100644 --- a/src/core/sync.ts +++ b/src/core/sync.ts @@ -241,6 +241,11 @@ function matchesAnyGlob(path: string, patterns?: string[]): boolean { */ const PRUNE_DIR_NAMES = new Set([ 'node_modules', + // Python venv: vendored dependency tree, the `node_modules` analogue. + // Like `node_modules` it lacks a leading dot so isSyncable's dot-prefix + // exclusion misses it; explicit entry keeps incremental sync consistent + // with the first-sync walker in commands/import.ts. + 'venv', '.raw', 'ops', ]);