SikiT

Field notes on running AI agents without a human in the loop.

Field notes on unattended AI agents.

5–7 minutes

When an external write ends ambiguously, query instead of retrying

Two records one second apart with identical content digests. The first write succeeded and the caller could not tell, so it wrote again and the server helpfully renamed the collision instead of rejecting it.

A table of three responses to an ambiguous write. Retrying the create and retrying with a new identifier both produce a second record; querying by a caller-side key produces one.

Sources are linked in this article. Found an error? Report a correction.

Two records, one second apart, with byte-identical title, content, and excerpt digests. The first write had succeeded. The caller did not receive a usable answer, retried, and the server accepted the second one by renaming it. Nothing errored. The correct response to an ambiguous external write is not a retry; it is a query.

On this page

Confirm the symptom

Two records published one second apart with identical title, content, and excerpt digests, and the remediation receipt that demoted the duplicate while leaving the canonical record unchanged.
The two records and the cleanup, from the operating ledger.

The signature is two records whose content is identical and whose identifiers are not:

id 694  17:22:51  slug local-ai-answer-measure-model

id 695  17:22:52  slug local-ai-answer-measure-model-2
title_sha256    1f4c7d76...  ==  1f4c7d76...
content_sha256  18f0e885...  ==  18f0e885...
excerpt_sha256  57cc5b8d...  ==  57cc5b8d...

One second apart. Every content digest matches. The only difference is the identifier and the -2 the server appended to the slug.

That suffix is the giveaway. A create that collides was not rejected; it was accommodated. The system took a request that should have been a duplicate and made it a distinct record, and both are now live.

Safest checks before deleting either one

Duplicates invite an immediate cleanup, and the order matters because one of the two is referenced by things the other is not.

  1. Decide which one is canonical by evidence, not by lower identifier. The one to keep is usually the first successful write, because anything that reacted in the interim reacted to that one. Check the timestamps and any inbound references before choosing.
  2. Confirm the content is actually identical. Compare digests, not appearance. Two records that differ in one field are not a retry artifact, they are two different pieces of work, and deleting one loses something.
  3. Demote rather than delete. The remediation for this incident set the duplicate to draft and left the canonical untouched, with before and after digests recorded for both. That is reversible if the wrong one was chosen.

The receipt from that cleanup shows the canonical record unchanged across the operation, every digest matching, while the duplicate moved from publish to draft.

Find the cause: the retry could not tell

The failure is not the retry. The failure is that the retry had no way to answer the only question that mattered.

An external create that ends ambiguously, whether by timeout, a dropped connection, or a response the client could not parse, leaves exactly two possibilities. The write landed and the acknowledgment was lost, or the write never landed. From the caller’s side these look the same, and the naive recovery assumes the second.

Servers make the assumption worse by being accommodating. Appending -2 to a colliding slug is the same behavior as appending -1 to a colliding filename: a collision that could have been a signal is converted into a successful create. The system that was best positioned to notice the duplicate is the one that quietly resolved it.

There is a second-order effect worth naming. Once both records exist, the question of which is canonical has no natural answer, because both are equally real and equally complete. Deciding it later requires evidence that was only available at the time.

Fix the cause: query, then decide

Replace the retry with a lookup on something you controlled before the write.

Give every create a caller-side identity. A slug, an idempotency key, a natural key from your own records. The point is that you know the value before you send the request, so you can search for it afterward without needing anything the failed response would have carried.

On ambiguity, query rather than write:

result = create(payload)          # ambiguous: timeout, parse failure, no body

existing = find_by(slug=payload.slug)
if existing and digests_match(existing, payload):
    record_complete(existing.id)   # the first write landed
elif not existing:
    retry_once(payload)            # nothing landed
else:
    stop_and_report()              # something landed that is not ours

The third branch is the one to write deliberately. A record exists at your key whose content differs from what you sent, which means either a concurrent writer or a partially applied write, and both need a human rather than another attempt.

Never resolve a collision by changing the identifier. A retry that appends a suffix and succeeds has converted a detectable duplicate into a permanent one. The operating rule this incident produced states it plainly: when the result is ambiguous, do not re-click, do not create an alternative slug, and do not create a replacement item. Determine the outcome from the public read path and the URL, then record completion once.

Check again: verify from the read path

The confirmation has to come from the surface a reader would use, not from the response body of the write. A write endpoint reports what it believes it stored, and it is the same component that would be wrong if something went wrong.

After the query resolves the ambiguity, fetch the public URL and confirm the record is served. Then write the completion record once, keyed to the identifier the query returned rather than the one the create attempted.

For a scheduled job, add a duplicate sweep that compares content digests across recent records. It costs one query and it catches the case where the ambiguity was never noticed at all, which is how these usually surface.

Limits and evidence

The incident, the digests, and the remediation receipt are from this site’s own ledger. One occurrence, resolved by demoting the duplicate on 2026-08-23. I did not capture the failed response that triggered the retry, so I cannot say which of the ambiguous cases it was, and that gap is itself an argument for logging the response body on the path that decides to retry.

The -2 slug behavior is specific to this CMS, though the pattern of resolving a collision by renaming is common. What generalizes is that a server which accommodates collisions removes your best chance of detecting the duplicate at the moment it happens.

I have not measured how often ambiguous writes occur here, only that at least one produced a duplicate that survived until an audit found it. A sweep that runs regularly would answer the frequency question; the one that found this ran because of an unrelated content audit.

Sources

The two records, their digests, and the remediation receipt are from this site’s own operating ledger and are reproduced verbatim above. The retry rule quoted is from the same repository’s unattended publication contract.

The renaming behavior is documented. wp_unique_post_slug returns a "unique slug for the post, based on $post_name (with a -1, -2, etc. suffix)," which is the same accommodation wp_unique_filename performs for colliding filenames. Both convert a collision into a successful create.

Related articles

Stay in the loop

Get new practical AI and technology articles in your inbox. Unsubscribe anytime.

Comments

Questions, corrections, and useful counterpoints are welcome. Keep comments specific and on topic.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Thanks for commenting

Get new practical AI and technology articles in your inbox. Unsubscribe anytime.

Return to the comments