返回 Skill 列表
extension
分类: 开发与工程无需 API Key

obsidian-common-errors

诊断并修复常见的Obsidian插件错误和异常。当遇到插件错误、调试失败的操作或解决Obsidian插件问题时使用。可以通过诸如“obsidian错误”、“修复obsidian插件”、“obsidian无法工作”、“调试obsidian插件”等短语触发。

person作者: jakexiaohubgithub

Obsidian Common Errors

Overview

Quick reference for the most common Obsidian plugin errors and their solutions.

Prerequisites

  • Obsidian plugin development environment set up
  • Access to Developer Console (Ctrl/Cmd+Shift+I)
  • Plugin source code access

Instructions

Step 1: Open Developer Console

Press Ctrl+Shift+I (Windows/Linux) or Cmd+Option+I (macOS) to open Developer Tools.

Step 2: Identify the Error

Check the Console tab for red error messages related to your plugin.

Step 3: Match Error to Solutions Below

Find your error type and apply the fix.

Error Handling

TypeError: Cannot read properties of undefined

Error Message:

TypeError: Cannot read properties of undefined (reading 'xyz')

Cause: Accessing a property on a null/undefined object, often when vault or workspace isn't ready.

Solution:

// WRONG: Direct access without check
const file = this.app.workspace.getActiveFile();
const content = await this.app.vault.read(file); // Error if file is null

// RIGHT: Null check first
const file = this.app.workspace.getActiveFile();
if (!file) {
  new Notice('No file is currently open');
  return;
}
const content = await this.app.vault.read(file);

Plugin failed to load

Error Message:

Plugin 'my-plugin' failed to load

Causes and Solutions:

  1. Syntax error in main.js:
# Check for syntax errors
node -c main.js
  1. Missing manifest.json fields:
{
  "id": "my-plugin",          // Required: unique identifier
  "name": "My Plugin",         // Required: display name
  "version": "1.0.0",          // Required: semver version
  "minAppVersion": "1.0.0",    // Required: minimum Obsidian version
  "description": "...",        // Required
  "author": "Your Name"        // Required
}
  1. No default export:
// WRONG: Named export
export class MyPlugin extends Plugin { }

// RIGHT: Default export
export default class MyPlugin extends Plugin { }

This plugin failed to load and has been disabled

Error Message:

This plugin failed to load and has been disabled. Check the developer console for more information.

Common Causes:

  1. Runtime error in onload():
// WRONG: Error thrown during load
async onload() {
  const data = await someAsyncOperation(); // Throws if fails
}

// RIGHT: Wrap in try-catch
async onload() {
  try {
    const data = await someAsyncOperation();
  } catch (error) {
    console.error('Failed to load data:', error);
    new Notice('Plugin initialization failed');
  }
}
  1. Incorrect module import:
// WRONG: Importing from wrong package
import { Something } from 'wrong-package';

// RIGHT: Check external modules in build config
// esbuild.config.mjs
external: ['obsidian', 'electron', '@codemirror/*', '@lezer/*'],

Command not found / Command not registered

Error Message:

Command 'my-plugin:my-command' not found

Cause: Command not registered or wrong command ID.

Solution:

// Verify command registration
this.addCommand({
  id: 'my-command',  // ID without plugin prefix
  name: 'My Command',
  callback: () => {
    // Handler
  },
});

// Obsidian automatically prefixes with plugin ID:
// Full ID becomes: 'my-plugin:my-command'

View type not registered

Error Message:

View type 'custom-view' not registered

Cause: Trying to use a view before registering it.

Solution:

// MUST register view in onload, BEFORE using it
async onload() {
  // 1. Register view type first
  this.registerView(
    VIEW_TYPE_CUSTOM,
    (leaf) => new CustomView(leaf)
  );

  // 2. Then you can activate it
  this.addCommand({
    id: 'open-view',
    name: 'Open View',
    callback: () => this.activateView(), // Now safe to call
  });
}

Settings not persisting

Error Message: No error, but settings reset on reload.

Cause: Missing saveData() call or wrong data structure.

Solution:

// WRONG: Modifying settings without saving
this.settings.myOption = newValue;

// RIGHT: Save after modifying
this.settings.myOption = newValue;
await this.saveSettings();

// Implement save properly:
async saveSettings() {
  await this.saveData(this.settings);
}

async loadSettings() {
  this.settings = Object.assign(
    {},
    DEFAULT_SETTINGS,
    await this.loadData()
  );
}

File not found / Path errors

Error Message:

Error: ENOENT: no such file or directory

Cause: Incorrect file path or file doesn't exist.

Solution:

// Always verify file exists
const file = this.app.vault.getAbstractFileByPath(path);

if (!file) {
  new Notice(`File not found: ${path}`);
  return;
}

if (!(file instanceof TFile)) {
  new Notice(`Not a file: ${path}`);
  return;
}

// Now safe to use
const content = await this.app.vault.read(file);

Memory leaks / Event handlers not cleaned up

Symptoms: Plugin slows down, duplicate events firing.

Cause: Event listeners not properly removed.

Solution:

// WRONG: Direct event listener
document.addEventListener('click', this.handleClick);

// RIGHT: Use registerDomEvent (auto-cleanup)
this.registerDomEvent(document, 'click', this.handleClick.bind(this));

// WRONG: Direct workspace event
this.app.workspace.on('file-open', callback);

// RIGHT: Use registerEvent (auto-cleanup)
this.registerEvent(
  this.app.workspace.on('file-open', callback)
);

Build errors: Cannot find module 'obsidian'

Error Message:

Cannot find module 'obsidian' or its corresponding type declarations

Solution:

# Verify obsidian types are installed
npm install obsidian@latest

# Check tsconfig.json
{
  "compilerOptions": {
    "moduleResolution": "node",
    "types": ["node"]
  }
}

# Note: 'obsidian' is external - not bundled
# Check esbuild.config.mjs
external: ['obsidian'],

Examples

Debug Logging Helper

// Add at top of main.ts for debugging
const DEBUG = true;

function debug(...args: any[]) {
  if (DEBUG) {
    console.log('[MyPlugin]', ...args);
  }
}

// Use throughout code
debug('Loading settings', this.settings);
debug('Processing file', file.path);

Quick Diagnostic Commands

// Add debug commands during development
this.addCommand({
  id: 'debug-dump-settings',
  name: 'Debug: Dump Settings',
  callback: () => {
    console.log('Settings:', JSON.stringify(this.settings, null, 2));
  }
});

this.addCommand({
  id: 'debug-list-views',
  name: 'Debug: List Open Views',
  callback: () => {
    const leaves = this.app.workspace.getLeavesOfType('markdown');
    console.log('Open views:', leaves.length);
    leaves.forEach(leaf => {
      console.log('-', leaf.view.file?.path);
    });
  }
});

Escalation Path

  1. Check Developer Console for errors
  2. Collect evidence with obsidian-debug-bundle
  3. Search Obsidian Forum
  4. Check GitHub Issues
  5. Ask in Obsidian Discord

Resources

Next Steps

For comprehensive debugging, see obsidian-debug-bundle.