BloopAI/vibe-kanban · error

Failed to update ${mutation.name} (or server-provided messag

Error message

Failed to update ${mutation.name} (or server-provided message via parseResponseError)

What it means

Thrown in the ElectricSQL collection onUpdate mutation handler when the PATCH request to `${mutation.url}/{key}` returns a non-ok HTTP status. It surfaces either the server-provided error message extracted by parseResponseError or the fallback 'Failed to update <name>'. This is the optimistic-update write path failing at the API layer, so the local mutation cannot be confirmed with a txid.

Source

Thrown at packages/web-core/src/shared/lib/electric/collections.ts:711

        const mutationItem = transaction.mutations[0];
        if (!mutationItem?.key) {
          throw new Error(`Failed to update ${mutation.name}: missing key`);
        }

        const response = await makeRequest(
          `${mutation.url}/${mutationItem.key}`,
          {
            method: 'PATCH',
            body: JSON.stringify(mutationItem.changes),
          }
        );

        if (!response.ok) {
          const message = await parseResponseError(
            response,
            `Failed to update ${mutation.name}`
          );
          throw new Error(message);
        }

        const result = (await response.json()) as { txid: number };
        txids = [result.txid];
      }

      maybeRefreshFallbackAfterMutation(sourceKey);

      if (isSourceFallbackLocked(sourceKey)) {
        return;
      }

      return { txid: txids };
    },

    onDelete: async ({
      transaction,
    }: MutationFnParams): Promise<{ txid: number[] } | void> => {

View on GitHub (pinned to 4deb7eca8f)

Solutions

  1. Read the thrown message: if it contains a server message, fix the payload/validation issue it names; if it's the fallback, inspect the network tab for the actual status code of the PATCH request.
  2. If 401/403, re-authenticate so the request carries a valid bearer token/session cookie, then retry the mutation.
  3. If 404, refresh the collection so the deleted item disappears locally instead of retrying the PATCH.
  4. If 5xx, check backend logs/health and retry once the server recovers; the Electric collection will retry pending mutations on reconnect.

Example fix

// before: blind retry of a failing PATCH
await collection.update(item, { changes });
// after: guard with up-to-date data and handle failure
const fresh = await fetch(`${mutation.url}/${item.id}`);
if (!fresh.ok) {
  await collection.refetch(); // record gone/stale, resync instead of PATCH
  return;
}
await collection.update(item, { changes });
Defensive patterns

Strategy: try-catch

Validate before calling

const res = await fetch(`${mutation.url}/${item.id}`, { method: 'HEAD' });
if (!res.ok) throw new Error(`Record ${item.id} not updatable (HTTP ${res.status})`);

Try / catch

try {
  await collection.update(item, { changes });
} catch (e) {
  if (e instanceof Error && e.message.startsWith('Failed to update')) {
    console.error('Update rejected:', e.message);
    await collection.refetch();
  } else throw e;
}

Prevention

When it happens

Trigger: Any non-2xx response from the PATCH to the collection's REST endpoint: 400 on invalid changes payload, 401/403 on auth failure, 404 when the record key no longer exists, 409/422 on validation or conflict, 5xx on backend crash.

Common situations: Editing a task that another session deleted (404); submitting fields that violate backend validation; an expired session token; the backend restarting mid-edit.

Understand the failure class

Background: 'Something went wrong' / 'Request failed (500)' / 'HTTP error! status: 404' — what failed HTTP requests actually mean and how to find the real cause — this error's family across 28 libraries.

Related errors


AI-assisted analysis of BloopAI/vibe-kanban@4deb7eca8f (2026-08-29). Data as JSON: /api/errors/eeb7ec0e621d9eb8. Report an issue: GitHub.