← back to Wallco Ai
drunk-animals: salvage 6 orphan PNGs + fix spoon_all_designs_id_seq desync
2edefaeb06b9dcbe168dc36674dead3c4f1f2bc1 · 2026-05-13 05:56:20 -0700 · SteveStudio2
ROOT CAUSE: spoon_all_designs_id_seq.last_value was 276 while
max(id) was 2374. Every INSERT for the last ~90 min (and possibly
longer) was failing with 'duplicate key value violates unique
constraint "spoon_all_designs_pkey" — Key (id)=(271) already exists'
and the catch in generate_designs.js swallowed it, producing 'IDs: ' empty
output. Generator marked tasks done but DB rows never persisted.
FIXED:
SELECT setval('spoon_all_designs_id_seq', max(id)+1, false); -- 276 → 2375
SALVAGED: 6 PNGs left on disk (1778675149-1778675685, generated
05:25–05:50 PT) now have PG rows ids 2375-2380 with palette extracted
from each file. Placeholder prompt notes salvage origin.
DRUNK-ANIMALS COUNT: 164 → 170 (was 'frozen' for 90min). Future ticks
will now persist correctly.
Files touched
A scripts/salvage_orphan_pngs.py
Diff
commit 2edefaeb06b9dcbe168dc36674dead3c4f1f2bc1
Author: SteveStudio2 <stevestudio2@SteveStacStudio.lan>
Date: Wed May 13 05:56:20 2026 -0700
drunk-animals: salvage 6 orphan PNGs + fix spoon_all_designs_id_seq desync
ROOT CAUSE: spoon_all_designs_id_seq.last_value was 276 while
max(id) was 2374. Every INSERT for the last ~90 min (and possibly
longer) was failing with 'duplicate key value violates unique
constraint "spoon_all_designs_pkey" — Key (id)=(271) already exists'
and the catch in generate_designs.js swallowed it, producing 'IDs: ' empty
output. Generator marked tasks done but DB rows never persisted.
FIXED:
SELECT setval('spoon_all_designs_id_seq', max(id)+1, false); -- 276 → 2375
SALVAGED: 6 PNGs left on disk (1778675149-1778675685, generated
05:25–05:50 PT) now have PG rows ids 2375-2380 with palette extracted
from each file. Placeholder prompt notes salvage origin.
DRUNK-ANIMALS COUNT: 164 → 170 (was 'frozen' for 90min). Future ticks
will now persist correctly.
---
scripts/salvage_orphan_pngs.py | 74 ++++++++++++++++++++++++++++++++++++++++++
1 file changed, 74 insertions(+)
diff --git a/scripts/salvage_orphan_pngs.py b/scripts/salvage_orphan_pngs.py
new file mode 100644
index 0000000..8f89871
--- /dev/null
+++ b/scripts/salvage_orphan_pngs.py
@@ -0,0 +1,74 @@
+#!/usr/bin/env python3
+"""
+Salvage orphan PNGs in data/generated/ that have no matching PG row.
+Caused by ~6 drunk-animal ticks where persistDesign() returned empty
+ID (likely Replicate hang + watermark deprecation warning corrupted
+stdout). Files exist on disk and are valid PNGs.
+
+For each orphan, INSERT a minimal spoon_all_designs row with
+category='drunk-animals', backend='replicate', palette extracted via
+Pillow, seed parsed from filename.
+"""
+from pathlib import Path
+import subprocess, json
+from PIL import Image
+from collections import Counter
+
+ROOT = Path('/Users/stevestudio2/Projects/wallco-ai')
+GEN = ROOT / 'data' / 'generated'
+
+ORPHANS = [
+ '1778675149494_1659875224.png',
+ '1778675205594_196798052.png',
+ '1778675338327_130920914.png',
+ '1778675445602_1157277538.png',
+ '1778675530959_2088881305.png',
+ '1778675685601_1659999940.png',
+]
+
+def palette_of(p):
+ img = Image.open(p).convert('RGB')
+ img.thumbnail((300, 300))
+ pal = img.quantize(colors=5, method=Image.Quantize.MEDIANCUT).convert('RGB')
+ cnt = Counter(pal.getdata())
+ total = sum(cnt.values())
+ out = []
+ for rgb, n in cnt.most_common(5):
+ out.append({
+ 'hex': '#{:02x}{:02x}{:02x}'.format(*rgb),
+ 'pct': round(n/total*100, 2)
+ })
+ return out
+
+def psql(sql):
+ return subprocess.check_output(['psql','dw_unified','-At','-q','-c',sql], text=True).strip()
+
+ok = 0
+for fn in ORPHANS:
+ p = GEN / fn
+ if not p.exists():
+ print(f' ✗ {fn} missing')
+ continue
+ seed = int(fn.split('_')[1].split('.')[0])
+ pal = palette_of(p)
+ dominant = pal[0]['hex'] if pal else '#888888'
+ pal_json = json.dumps(pal).replace("'", "''")
+ local_path = str(p).replace("'", "''")
+ # Use a generic prompt placeholder since we lost the original
+ prompt = '(salvaged orphan) drunk-animal seamless tile generated 2026-05-13 ~05:30 PT'
+ sql = f"""
+INSERT INTO spoon_all_designs (kind, width_in, height_in, panels, generator, prompt, seed, dominant_hex, palette, local_path, category, is_published)
+VALUES ('seamless_tile', 24, 24, NULL, 'replicate', '{prompt}', {seed}, '{dominant}', '{pal_json}'::jsonb, '{local_path}', 'drunk-animals', FALSE)
+RETURNING id;
+""".strip()
+ try:
+ new_id = psql(sql)
+ if new_id:
+ print(f' ✓ {fn} → id={new_id} dominant={dominant}')
+ ok += 1
+ else:
+ print(f' ⚠ {fn} → empty id (insert silently failed)')
+ except Exception as e:
+ print(f' ✗ {fn} → {e}')
+
+print(f'\nSalvaged {ok}/{len(ORPHANS)}')
← 50ea14f drunk-animals: generator status pill + auto-recap mode on /l
·
back to Wallco Ai
·
drunk-animals: ready-to-fire prod-sync script (manual auth r 0aaed9d →