BloopAI/vibe-kanban · error

error.message || 'Failed to bulk update projects' (dynamic)

Error message

error.message || 'Failed to bulk update projects' (dynamic)

What it means

bulkUpdateProjects PATCHes multiple project changes to the remote API. On a non-ok HTTP response it parses the response JSON and throws Error with the server-provided `message`, falling back to the generic 'Failed to bulk update projects' string when the error body has no message field (or the body is not JSON). The thrown value is the rejection of the returned Promise<void>.

Source

Thrown at packages/web-core/src/shared/lib/remoteApi.ts:121

}

export interface BulkUpdateProjectItem {
  id: string;
  changes: Partial<UpdateProjectRequest>;
}

export async function bulkUpdateProjects(
  updates: BulkUpdateProjectItem[]
): Promise<void> {
  const response = await makeRequest('/v1/projects/bulk', {
    method: 'POST',
    body: JSON.stringify({
      updates: updates.map((u) => ({ id: u.id, ...u.changes })),
    }),
  });
  if (!response.ok) {
    const error = await response.json();
    throw new Error(error.message || 'Failed to bulk update projects');
  }
}

export async function bulkUpdateIssues(
  updates: BulkUpdateIssueItem[]
): Promise<void> {
  const response = await makeRequest('/v1/issues/bulk', {
    method: 'POST',
    body: JSON.stringify({
      updates: updates.map((u) => ({ id: u.id, ...u.changes })),
    }),
  });
  if (!response.ok) {
    const error = await response.json();
    throw new Error(error.message || 'Failed to bulk update issues');
  }
}

View on GitHub (pinned to 4deb7eca8f)

Solutions

  1. Re-authenticate / refresh the session token and retry the request
  2. Log the caught error.message and response status to identify which update item the server rejected; validate ids exist before batching
  3. Reduce batch size or split updates to isolate the failing item
  4. If self-hosted, verify VITE_VK_SHARED_API_BASE points to a healthy backend returning JSON errors

Example fix

// before
await bulkUpdateProjects(updates); // unhandled rejection
// after
try {
  await bulkUpdateProjects(updates);
} catch (e) {
  notify.error(e instanceof Error ? e.message : 'Bulk update failed');
}
Defensive patterns

Strategy: try-catch

Validate before calling

if (!updates.length) return; const ids = new Set(projects.map(p => p.id)); if (updates.some(u => !ids.has(u.id))) throw new Error('unknown project id in batch');

Type guard

function isApiErrorBody(x: unknown): x is { message: string } { return typeof x === 'object' && x !== null && typeof (x as any).message === 'string'; }

Try / catch

try {
  await bulkUpdateProjects(updates);
} catch (e) {
  const msg = e instanceof Error ? e.message : 'Failed to bulk update projects';
  notify.error(msg);
}

Prevention

When it happens

Trigger: Any non-2xx response from PATCH bulk-update-projects: validation failures on one of the update items, stale/invalid auth token, project id not found, or server 500. Also fires when the server returns an error body without a `message` property.

Common situations: Expired JWT after idle time, bulk-pasting a list containing already-deleted project ids, self-hosted gateway returning HTML error pages (JSON parse then fallback message), rate limiting under a large batch.

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/973a933f58e9a3e2. Report an issue: GitHub.