moeru-ai/airi · error · Error
Failed to bookmark character
Error message
Failed to bookmark character
What it means
Thrown by CharactersService.bookmarkRemote when POST /v1/characters/:id/bookmark returns non-ok. Symmetric to likeRemote: expects a parseable character back; aborts on failure. Message discards status.
Source
Thrown at packages/stage-ui/src/services/characters.ts:229
options?.abortSignal?.throwIfAborted()
}
async function likeRemote(client: CharactersRemoteClient, id: string, options?: CharacterServiceOptions): Promise<Character> {
options?.abortSignal?.throwIfAborted()
const res = await client.api.v1.characters[':id'].like.$post({ param: { id } }, requestOptions(options))
if (!res.ok)
throw new Error('Failed to like character')
const data = await res.json()
options?.abortSignal?.throwIfAborted()
return parse(data)
}
async function bookmarkRemote(client: CharactersRemoteClient, id: string, options?: CharacterServiceOptions): Promise<Character> {
options?.abortSignal?.throwIfAborted()
const res = await client.api.v1.characters[':id'].bookmark.$post({ param: { id } }, requestOptions(options))
if (!res.ok)
throw new Error('Failed to bookmark character')
const data = await res.json()
options?.abortSignal?.throwIfAborted()
return parse(data)
}
return {
buildLocal,
fetchRemote,
fetchRemoteById,
createRemote,
updateRemote,
removeRemote,
likeRemote,
bookmarkRemote,
}
}
View on GitHub (pinned to 27111382b4)
Solutions
- Handle 404 by removing the stale character from the UI.
- Re-authenticate on 401/403 before retrying.
- On 409/already-bookmarked, reconcile local state to 'bookmarked'.
- Include res.status for status-based handling.
Example fix
// before
if (!res.ok)
throw new Error('Failed to bookmark character')
// after
if (!res.ok) {
if (res.status === 409)
return parse(await res.json().catch(() => ({})))
throw new Error(`Failed to bookmark character ${id} (status ${res.status})`)
} Defensive patterns
Strategy: try-catch
Validate before calling
function isValidCharacterId(id: string): boolean {
return typeof id === 'string' && id.length > 0
}
if (!isValidCharacterId(id))
throw new Error(`Invalid character id: ${id}`)
await bookmarkRemote(client, id) Try / catch
try {
return await bookmarkRemote(client, id)
}
catch (error) {
// Patch service to expose status; on 409 reconcile to 'bookmarked', on 404 remove locally, on 401/403 re-auth.
throw error
} Prevention
- Reconcile local state to 'bookmarked' on 409 (already bookmarked).
- Embed res.status in the service error for status-based handling.
- Handle 404 by removing the stale character from the UI.
When it happens
Trigger: client.api.v1.characters[':id'].bookmark.$post({ param: { id } }) resolves with ok=false. Typical: 401/403 (not authenticated), 404 (character deleted), 409 (already bookmarked), 500 (server).
Common situations: Bookmarking a deleted character; expired session; double-bookmark race; permission mismatch.
Related errors
- Failed to fetch characters
- Failed to fetch character
- Failed to create character
- Failed to update character
- Failed to remove character
AI-assisted analysis of moeru-ai/airi@27111382b4 (2026-08-12).
Data as JSON: /api/errors/0fbbf9d219002f12.
Report an issue: GitHub.