BloopAI/vibe-kanban · error

Failed to fetch fallback ${args.shape.table} (or server-prov

Error message

Failed to fetch fallback ${args.shape.table} (or server-provided message via parseResponseError)

What it means

refreshNow in the fallback sync path fetches the full table snapshot from the fallback endpoint; if the response is not ok it builds a message via parseResponseError (server's `message`/`error` field if parseable, else 'Failed to fetch fallback <table>') and throws. The thrown message is then reported via args.reportError and the collection may be marked ready with empty/partial data, so users may only see this via the sync error callback.

Source

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

    const refreshNow = async () => {
      if (refreshPromise) {
        return refreshPromise;
      }

      refreshPromise = (async () => {
        try {
          const response = await makeRequest(
            buildFallbackRequestPath(args.shape.fallbackUrl, args.params),
            { method: 'GET', cache: 'no-store' }
          );

          if (!response.ok) {
            const message = await parseResponseError(
              response,
              `Failed to fetch fallback ${args.shape.table}`
            );
            throw new Error(message);
          }

          const payload = (await response.json()) as unknown;
          const rows = extractFallbackRows(payload, args.shape.table);
          fallbackSnapshotCache.set(args.sourceKey, rows);

          if (!isCleanedUp) {
            applySnapshot(syncParams, rows);
          }
        } catch (error) {
          if (isAbortError(error)) return;

          const message =
            error instanceof Error ? error.message : 'Fallback fetch failed';
          args.reportError({ message });

          if (!isCleanedUp && !syncParams.collection.isReady()) {
            syncParams.markReady();

View on GitHub (pinned to 4deb7eca8f)

Solutions

  1. Read the reported message: if it's the fallback text, check response status by inspecting the endpoint manually (curl the fallbackUrl with the same params).
  2. Fix auth (re-login) if the underlying status is 401/403 — the fallback fetch shares the session.
  3. Correct args.shape.fallbackUrl / params so buildFallbackRequestPath targets an existing list route.
  4. Since refreshNow swallows the throw into reportError, attach an onElectricUnavailable/reportError handler that surfaces status ≥ 500 to the UI and retries.

Example fix

// before
createCollection({ shape: { url, table: 'tasks', fallbackUrl: '/wrong-path' } });
// after
createCollection({ shape: { url, table: 'tasks', fallbackUrl: '/api/tasks' },
  reportError: (e) => showErrorToast(e.message) });
Defensive patterns

Strategy: retry

Validate before calling

const probe = await makeRequest(buildFallbackRequestPath(shape.fallbackUrl, params), { method: 'HEAD' });
if (!probe.ok) console.warn('Fallback endpoint unhealthy:', probe.status);

Type guard

function isFallbackFetchError(msg: string): boolean {
  return msg.startsWith('Failed to fetch fallback ');
}

Try / catch

createCollection({
  reportError: (err) => {
    if (isFallbackFetchError(err.message)) {
      scheduleRetryWithBackoff();
      showOfflineBanner();
    }
  },
});

Prevention

When it happens

Trigger: Fallback endpoint returns 401/403 (not authenticated), 404 (fallbackUrl wrong or route missing), 422 (bad params in buildFallbackRequestPath), or 5xx (backend/DB down) during initial fallback sync or a periodic/invalidated refresh.

Common situations: Electric unavailable and fallback URL misconfigured in the shape definition; auth cookie expired so fallback GET gets 401; backend deployment removed the plain REST list route the fallback relies on; request params contain characters needing encoding that break the route.

Related errors


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