← back to Dw Marketing Reels
Harden video-runner: retry transient API rate-limits before erroring
6eb3061996fa4bd530a20ac1199ead5b5d277d4d · 2026-07-22 07:13:20 -0700 · Steve
Root cause of the studio host's 'claude exit 1' renders was a transient Anthropic
throttle ('Server is temporarily limiting requests'), which permanently killed the
job with no retry. Now:
- capture claude stderr, classify transient (rate-limit/overloaded/429/529/reset)
- retry with exponential backoff (VIDEO_MAX_TRIES=3, VIDEO_BACKOFF_MS=20000)
- record attempts + a human-readable reason in job.note (not opaque 'exit 1')
- console surfaces the last few errored renders with their reason so failures
don't vanish silently
Applies to both the manual studio buttons and the new suggestions 'Use it' flow.
Files touched
Diff
commit 6eb3061996fa4bd530a20ac1199ead5b5d277d4d
Author: Steve <steve@designerwallcoverings.com>
Date: Wed Jul 22 07:13:20 2026 -0700
Harden video-runner: retry transient API rate-limits before erroring
Root cause of the studio host's 'claude exit 1' renders was a transient Anthropic
throttle ('Server is temporarily limiting requests'), which permanently killed the
job with no retry. Now:
- capture claude stderr, classify transient (rate-limit/overloaded/429/529/reset)
- retry with exponential backoff (VIDEO_MAX_TRIES=3, VIDEO_BACKOFF_MS=20000)
- record attempts + a human-readable reason in job.note (not opaque 'exit 1')
- console surfaces the last few errored renders with their reason so failures
don't vanish silently
Applies to both the manual studio buttons and the new suggestions 'Use it' flow.
---
public/index.html | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/public/index.html b/public/index.html
index 1b02d42..57e90fb 100644
--- a/public/index.html
+++ b/public/index.html
@@ -391,6 +391,10 @@ async function loadJobs() {
}).join('');
if (active.length && !VAUTO) $('#jobs').insertAdjacentHTML('afterbegin',
'<span class="badge err" title="Set VIDEO_AUTORUN=1 on the studio host to auto-render">⚠ host not armed — queued jobs wait for a studio session</span>');
+ // surface the last few errored renders (with reason) so failures don't vanish silently
+ const failed = jobs.filter(j => j.status === 'error').slice(0, 3);
+ $('#jobs').insertAdjacentHTML('beforeend', failed.map(j =>
+ `<span class="badge err" title="${escapeAttr(j.note||'render failed')}">✗ ${escapeHtml(j.kind)} · ${escapeHtml(j.note||'failed')}</span>`).join(''));
$('#jobsInfo').textContent = active.length ? `(${active.length} queued / running)` : '';
if (active.length) setTimeout(() => { loadJobs(); loadVideos(); }, 4000);
}
← c0278de auto-save: 2026-07-22T07:12:00 (3 files) — data/new-arrivals
·
back to Dw Marketing Reels
·
video-runner: give renders narrated audio via auto-resolved 8227e20 →