Two workflows, one shared assumption
The split was reasonable: rendering is slow and can fail, uploading is quick, so the two live in separate workflows joined by a render queue in Google Sheets. The Creator's only protection against duplicates was its own read of the topic queue, filtered to rows whose status is still unused. That status was flipped by the Publisher, after a successful upload.
How the same topic got rendered twice
The Creator can't see the render queue. If the Publisher had not yet uploaded the previous ready row, the topic's status hadn't changed, so the next Creator run read the same row and rendered it again. It happened twice, each time about one Creator interval after the first render.
The fix: claim at pickup
A new Google Sheets update node, Mark Topic Claimed, sits between the check that a topic is available and the node that starts the render. It sets the status the instant the Creator picks the row. The Publisher's own mark-used step stays, and now rewrites the same value harmlessly.
The other half matters just as much. A Reset Topic On Failure node, fanned out from the branch that runs when every render attempt has failed, puts the status back to unused. Without it, a topic that never produced a video stays claimed forever. That branch also sends a Telegram alert, and putting the two side by side has a catch: on one occasion the alert node crashed on an HTML formatting error and the reset never ran, leaving two topics stuck as used with no video. The Telegram parse-mode article covers that crash.
Cleaning up what had already shipped
The older upload of each pair was left alone. The newer duplicate was renamed through the API with a title, description and tags in the channel's normal style, and all 18 videos were re-read to confirm every title and description was unique. I only found the duplicates because I audited the channel through the API; the execution log showed nothing wrong at any point.
The rule
Any producer and publisher pair that share a queue needs the producer to claim its item on pickup rather than rely on the publisher's later mark. It is a different bug from matching rows on a non-unique column: that one marks the wrong row after publishing, while this one never marks the right row soon enough.
n8n Automation Hub