How do I resolve a 409 concurrency conflict?
Handle optimistic-concurrency 409 conflicts when writing to the Unison brain: re-read the current version, merge, and retry.
I got a 409 conflict error when writing a page. What do I do?
Unison uses optimistic concurrency control for page writes. If two writers try to update the same page simultaneously, one will win and the other will receive a 409. The response body will have "code": "conflict".
This is intentional — it prevents silent data loss from last-write-wins semantics.
The fix: read, merge, retry
- Re-read the current version of the page to get the latest content and version identifier.
- Merge your intended changes with the current version.
- Retry the write with the updated content.
async function writeWithRetry(path: string, newContent: string, token: string) {
for (let attempt = 0; attempt < 3; attempt++) {
// Read current version — capture contentHash for optimistic concurrency
const current = await fetch(
`https://brain.unisonlabs.ai/v1/brain/doc?path=${encodeURIComponent(path)}`,
{ headers: { Authorization: `Bearer ${token}` } },
).then(r => r.json());
// Merge (application-specific logic)
const merged = mergeContent(current.bodyMd, newContent);
// Attempt in-place edit with expectedContentHash — 409 means someone else wrote first
const res = await fetch(`https://brain.unisonlabs.ai/v1/brain/doc`, {
method: 'PATCH',
headers: { Authorization: `Bearer ${token}`, 'content-type': 'application/json' },
body: JSON.stringify({
path,
oldStr: current.bodyMd,
newStr: merged,
expectedContentHash: current.contentHash,
}),
});
if (res.ok) return res;
if (res.status !== 409) throw new Error(`Unexpected status ${res.status}`);
// 409 — re-read and retry
}
throw new Error('Concurrency conflict retries exhausted');
}Avoiding conflicts in the first place
- Use distinct paths. If different agents write different facts, give each its own page path rather than all writing to a single shared file.
- Write to
/private/per actor. Each actor's private namespace is isolated, so per-user writes never conflict with each other. - Use append-style facts. For logs or timelines, append new entries at a unique timestamped subpath rather than rewriting the same file.
How do I handle rate limit errors (429)?
Handle Unison 429 rate limit responses with exponential backoff and jitter to avoid thundering-herd retries.
Can I self-host the Unison brain?
Understand the current self-hosting options for Unison and what to consider if data residency or air-gap requirements apply.