danielmiessler/Fabric · error · Error

responseData.error || 'Failed to save to Obsidian'

Error message

responseData.error || 'Failed to save to Obsidian'

What it means

Thrown in ChatInput.svelte when the POST to the Obsidian save endpoint returns non-ok. The real reason is in responseData.error from the server — typical causes are the Obsidian vault path not configured or not found, the notes directory missing, or a file write failure. If the server sends a non-JSON error page (e.g. a 404 HTML page from SvelteKit for a wrong route), response.json() itself throws before this line and you get a JSON parse error instead.

Source

Thrown at web/src/lib/components/chat/ChatInput.svelte:177

    }

    try {
      const response = await fetch('/obsidian', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({
          pattern: $selectedPatternName,
          noteName: $obsidianSettings.noteName,
          content
        })
      });

      const responseData = await response.json();
      
      if (!response.ok) {
        throw new Error(responseData.error || 'Failed to save to Obsidian');
      }
      // Add this after successful save
      updateObsidianSettings({ 
      saveToObsidian: false,  // Reset the save flag
      noteName: ''           // Clear the note name
      });
      toastStore.success(responseData.message || `Saved to Obsidian: ${responseData.fileName}`);
    } catch (error) {
      console.error('Failed to save to Obsidian:', error);
      toastStore.error(error instanceof Error ? error.message : 'Failed to save to Obsidian');
    }
  }

  // Centralized language instruction logic in ChatService.ts; YouTube flow now passes plain transcript and system prompt
  function extractYouTubeURLs(input: string): string[] {
      const youtubePattern = /(?:https?:\/\/)?(?:www\.)?(?:youtube\.com\/watch\?v=[\w-]+(?:&[^\s]*)?|youtu\.be\/[\w-]+(?:\?[^\s]*)?)/gi;
      return input.match(youtubePattern) || [];
  }

View on GitHub (pinned to 338b89cfe9)

Solutions

  1. Check the browser Network tab: read the actual status and responseData.error for the failed request
  2. Open Obsidian settings in the UI and confirm the vault path / note name are set and the vault directory exists on the machine running the server
  3. Verify the fetch URL matches the actual route (e.g. /api/obsidian/save) — a wrong path returns SvelteKit's HTML 404 and breaks response.json()
  4. Guard the JSON parse so non-JSON error bodies still produce a readable message

Example fix

// before
const responseData = await response.json();
if (!response.ok) {
  throw new Error(responseData.error || 'Failed to save to Obsidian');
}

// after
const responseData = await response.json().catch(() => null);
if (!response.ok) {
  throw new Error(responseData?.error || `Failed to save to Obsidian (HTTP ${response.status})`);
}
Defensive patterns

Strategy: validation

Validate before calling

// Run before POSTing the save
if (!$obsidianSettings.noteName?.trim()) {
  toastStore.error('Set an Obsidian note name before saving');
  return;
}
if (!('vaultPath' in $obsidianSettings && $obsidianSettings.vaultPath)) {
  toastStore.error('Configure the Obsidian vault path first');
  return;
}

Try / catch

try {
  const response = await fetch('/api/obsidian/save', { method: 'POST', ... });
  const responseData = await response.json().catch(() => null);
  if (!response.ok) {
    throw new Error(responseData?.error || `Failed to save to Obsidian (HTTP ${response.status})`);
  }
  toastStore.success(responseData.message || `Saved to Obsidian: ${responseData.fileName}`);
} catch (error) {
  toastStore.error(error instanceof Error ? error.message : 'Failed to save to Obsidian');
}

Prevention

When it happens

Trigger: Saving a chat with Obsidian settings whose vault/base path is unset or wrong; the configured notes folder was moved or deleted; the endpoint route moved so the fetch hits SvelteKit's 404 handler (HTML body, json() throws); disk permission errors on the vault directory.

Common situations: First-time use without completing Obsidian settings, vault relocated after initial config, running the dev server against a different working directory so relative vault paths resolve elsewhere, endpoint path typo after a refactor.

Related errors


AI-assisted analysis of danielmiessler/Fabric@338b89cfe9 (2026-08-15). Data as JSON: /api/errors/744014724ff6b5af. Report an issue: GitHub.