moeru-ai/airi · error · Error
Failed to update character
Error message
Failed to update character
What it means
Thrown by CharactersService.updateRemote when PATCH /v1/characters/:id returns non-ok. The service sends an UpdateCharacterPayload and re-parses the updated character on success. Failure aborts before parsing, so the caller knows the update was not applied.
Source
Thrown at packages/stage-ui/src/services/characters.ts:199
async function createRemote(client: CharactersRemoteClient, payload: CreateCharacterPayload, options?: CharacterServiceOptions): Promise<Character> {
options?.abortSignal?.throwIfAborted()
const res = await client.api.v1.characters.$post({ json: payload }, requestOptions(options))
if (!res.ok)
throw new Error('Failed to create character')
const data = await res.json()
options?.abortSignal?.throwIfAborted()
return parse(data)
}
async function updateRemote(client: CharactersRemoteClient, id: string, payload: UpdateCharacterPayload, options?: CharacterServiceOptions): Promise<Character> {
options?.abortSignal?.throwIfAborted()
const res = await client.api.v1.characters[':id'].$patch({
param: { id },
json: payload,
}, requestOptions(options))
if (!res.ok)
throw new Error('Failed to update character')
const data = await res.json()
options?.abortSignal?.throwIfAborted()
return parse(data)
}
async function removeRemote(client: CharactersRemoteClient, id: string, options?: CharacterServiceOptions): Promise<void> {
options?.abortSignal?.throwIfAborted()
const res = await client.api.v1.characters[':id'].$delete({ param: { id } }, requestOptions(options))
if (!res.ok)
throw new Error('Failed to remove character')
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)View on GitHub (pinned to 27111382b4)
Solutions
- Handle 404 by notifying the user the character was removed and refreshing the list.
- Confirm ownership/permissions before enabling edit; re-authenticate on 401/403.
- Validate the UpdateCharacterPayload fields client-side before PATCHing.
- Include res.status and server validation detail in the error for form feedback.
Example fix
// before
if (!res.ok)
throw new Error('Failed to update character')
// after: branch on status
if (!res.ok) {
if (res.status === 404)
throw new NotFoundError(`Character ${id} no longer exists`)
throw new Error(`Failed to update character ${id} (status ${res.status})`)
} Defensive patterns
Strategy: try-catch
Validate before calling
function validateUpdatePayload(payload: UpdateCharacterPayload): string[] {
const errors: string[] = []
if ('name' in payload && !payload.name?.trim())
errors.push('name cannot be empty')
return errors
}
const issues = validateUpdatePayload(payload)
if (issues.length)
throw new Error('Invalid update: ' + issues.join(', '))
await updateRemote(client, id, payload) Try / catch
try {
return await updateRemote(client, id, payload)
}
catch (error) {
// Patch service to expose status; on 404 refresh list, on 401/403 re-auth, on 422 show field errors.
throw error
} Prevention
- Validate UpdateCharacterPayload client-side before PATCHing.
- Handle 404 by refreshing the list (character may have been deleted concurrently).
- Embed res.status in the service error to enable status-based reconciliation.
When it happens
Trigger: client.api.v1.characters[':id'].$patch({ param: { id }, json: payload }) resolves with ok=false. Typical: 400 (invalid update payload), 401/403 (not the owner / not authenticated), 404 (character deleted concurrently), 409 (conflict on unique fields), 500 (server).
Common situations: Editing a character another client just deleted (404); submitting invalid field values; permission mismatch (editing someone else's character); stale local copy causing a conflict.
Related errors
- Failed to create character
- Failed to fetch characters
- Failed to fetch character
- Failed to remove character
- Failed to like character
AI-assisted analysis of moeru-ai/airi@27111382b4 (2026-08-12).
Data as JSON: /api/errors/699a3c2481722495.
Report an issue: GitHub.