stablyai/orca · warning · LinearWriteFailure
unconfirmed
unconfirmed
Error message
Linear relation mutation could not be confirmed.
What it means
Thrown by runRelationMutation when the underlying mutation fails with a duplicate_id classification. Because relation creates carry no caller-supplied id, a duplicate may actually be a successful concurrent add that Linear rejects as duplicate — so the operation cannot be confirmed either way. Encoded as LinearWriteFailure kind 'unconfirmed' with the original error as cause; isAuthError errors are rethrown unchanged.
Source
Thrown at src/main/linear/issue-relation-mutation.ts:76
{ id: relationId }
)
)
if (raw.data?.issueRelationDelete?.success !== true) {
throw new LinearWriteFailure('failed', 'Linear relation removal failed')
}
}
async function runRelationMutation<T>(mutation: () => Promise<T>): Promise<T> {
try {
return await mutation()
} catch (error) {
if (isAuthError(error)) {
throw error
}
const failure = classifyLinearWriteFailure(error)
if (failure.kind === 'duplicate_id') {
// Why: relation creates have no caller-supplied id, so a duplicate can be a concurrent add.
throw new LinearWriteFailure(
'unconfirmed',
'Linear relation mutation could not be confirmed.',
error
)
}
throw failure
}
}
View on GitHub (pinned to 1136503c6a)
Solutions
- Treat kind 'unconfirmed' as a probable success: refetch the issue's relations to confirm whether the relation now exists.
- Debounce/disable the link button until the in-flight mutation settles.
- Make the create idempotent client-side by checking existing relations before re-submitting.
- Do not blindly retry — that can create a third duplicate.
Example fix
// before
await createLinearIssueRelation(client, input)
// after
try { await createLinearIssueRelation(client, input) }
catch (e) {
if (e instanceof LinearWriteFailure && e.kind === 'unconfirmed') {
return await findRelation(input.issueId, input.relatedIssueId, input.type)
}
throw e
} Defensive patterns
Strategy: fallback
Validate before calling
if (await findRelation(input.issueId, input.relatedIssueId, input.type)) return existingRelation
Type guard
function isLinearRelationUnconfirmed(e: unknown): e is LinearWriteFailure {
return e instanceof Error && (e as LinearWriteFailure).name === 'LinearWriteFailure' && (e as LinearWriteFailure).kind === 'unconfirmed'
} Try / catch
try { return await createLinearIssueRelation(client, input) }
catch (e) {
if (e instanceof LinearWriteFailure && e.kind === 'unconfirmed') return await findRelation(input.issueId, input.relatedIssueId, input.type) ?? null
throw e
} Prevention
- Debounce the 'Link issue' button to prevent concurrent creates.
- On 'unconfirmed', refetch relations to confirm rather than retrying.
- Check for an existing relation before submitting a create.
When it happens
Trigger: Two concurrent createLinearIssueRelation calls for the same issue pair (e.g. user double-submits, or two app tabs), causing Linear to return a duplicate_id error on the second. The first may have succeeded.
Common situations: Double-click on a 'Link issue' button. Optimistic UI re-firing after a network hiccup. Multi-window app usage.
Related errors
- failed
- failed
- unconfirmed
- Terminal input is locked by another client.
- Codex reset attempt journal identity changed
AI-assisted analysis of stablyai/orca@1136503c6a (2026-08-12).
Data as JSON: /api/errors/f3a15df9e2b4dfd2.
Report an issue: GitHub.