Repository: sxyazi/yazi (language: rust)

Issue:
Wrong error message when a plugin in package.toml but not exists in plugins folder
### What system are you running Yazi on?

Linux Wayland

### What terminal are you running Yazi in?

wezterm 20250223-153857-fd532a8c

### `yazi --debug` output

```Shell
❯ yazi --debug

Yazi
    Version: 25.2.26 (f80446fb 2025-02-27)
    Debug  : false
    Triple : x86_64-unknown-linux-gnu (linux-x86_64)
    Rustc  : 1.85.0 (4d91de4e 2025-02-17)

Ya
    Version: 25.2.26 (f80446fb 2025-02-27)

Emulator
    TERM                : Some("xterm-256color")
    TERM_PROGRAM        : Some("WezTerm")
    TERM_PROGRAM_VERSION: Some("20250223-153857-fd532a8c")
    Brand.from_env      : Some(WezTerm)
    Emulator.detect     : Emulator { kind: Left(WezTerm), light: false, cell_size: Some((16, 36)) }

Adapter
    Adapter.matches: Iip

Desktop
    XDG_SESSION_TYPE           : Some("wayland")
    WAYLAND_DISPLAY            : Some("wayland-1")
    DISPLAY                    : Some(":0")
    SWAYSOCK                   : None
    HYPRLAND_INSTANCE_SIGNATURE: Some("882f7ad7d2bbfc7440d0ccaef93b1cdd78e8e3ff_1740619561_1813804682")
    WAYFIRE_SOCKET             : None

SSH
    shared.in_ssh_connection: false

WSL
    WSL: false

Variables
    SHELL           : Some("/usr/bin/zsh")
    EDITOR          : Some("lvim")
    VISUAL          : Some("lvim")
    YAZI_FILE_ONE   : None
    YAZI_CONFIG_HOME: None
    YAZI_ZOXIDE_OPTS: None
    FZF_DEFAULT_OPTS: Some("--ansi --height=100% --reverse --cycle")

Text Opener
    default     : Some(Opener { run: "${EDITOR:-vi} \"$@\"", block: true, orphan: false, desc: "$EDITOR", for_: None, spread: true })
    block-create: Some(Opener { run: "${EDITOR:-vi} \"$@\"", block: true, orphan: false, desc: "$EDITOR", for_: None, spread: true })
    block-rename: Some(Opener { run: "${EDITOR:-vi} \"$@\"", block: true, orphan: false, desc: "$EDITOR", for_: None, spread: true })

Multiplexers
    TMUX               : false
    tmux version       : No such file or directory (os error 2)
    tmux build flags   : enable-sixel=Unknown
    ZELLIJ_SESSION_NAME: None
    Zellij version     : 0.41.2

Dependencies
    file          : 5.46
    ueberzugpp    : No such file or directory (os error 2)
    ffmpeg/ffprobe: 7.1 / ffprobe version N-116914-g8a314e3f11 Copyright (c) 2007-2024 the FFmpeg developers
    pdftoppm      : 25.02.0
    magick        : 7.1.1-44
    fzf           : 0.60.2
    fd/fdfind     : 10.2.0 / No such file or directory (os error 2)
    rg            : 14.1.1
    chafa         : 1.14.5
    zoxide        : 0.9.7
    7zz/7z        : No such file or directory (os error 2) / 24.09
    jq            : 1.7.1

Clipboard
    wl-copy/paste: 2.2.1 / 2.2.1
    xclip        : No such file or directory (os error 2)
    xsel         : No such file or directory (os error 2)


See https://yazi-rs.github.io/docs/plugins/overview#debugging on how to enable logging or debug runtime errors.
```

### Describe the bug

use `ya pack -a` a plugin, delete it from plugins folder, then enter `yazi`, the deprecated entry file warning shows,

![Image](https://github.com/user-attachments/assets/b96ea2cc-b87d-48e5-ae24-952d2f10a103)

It should be some like 'The plugin xxx is not exist Please check and install first'

### Minimal reproducer

use `ya pack -a` a plugin, delete it from plugins folder, then enter `yazi`

### Anything else?

_No response_

### Checklist

- [x] I tried the [latest nightly build](https://yazi-rs.github.io/docs/installation#binaries), and the issue is still reproducible
- [x] I updated the debug information (`yazi --debug`) input box to the nightly that I tried
- [ ] I can reproduce it after disabling all custom configs/plugins (`mv ~/.config/yazi ~/.config/yazi-backup`)


Discussion / hints:
Hey @zooeywm, I noticed that you did not correctly follow the issue template. Please ensure that:

- The bug can still be reproduced on the [newest nightly build](https://yazi-rs.github.io/docs/installation/#binaries).
- The debug information (`yazi --debug`) is updated for the newest nightly.
- All *required* fields in the checklist have been checked.

Issues with `needs info` will be marked ready once edited with the proper content, or closed after 2 days of inactivity.

> Issues with `needs info` will be marked ready once edited with the proper content, or closed after 2 days of inactivity.

The bug is caused by `~/.config/yazi`, so  (`mv ~/.config/yazi ~/.config/yazi-backup`) can not reproduce this bug

Looks like the warning doesn't consider the case that the plugin doesn't exist at all. Would you like to raise a PR to fix it? The code can be found in

https://github.com/sxyazi/yazi/blob/84d71bfa397f2a217ca06c0651984ce1fb3b2507/yazi-plugin/src/loader/loader.rs#L58-L81
> Looks like the warning doesn't consider the case that the plugin doesn't exist at all. Would you like to raise a PR to fix it? The code can be found in
> 
> https://github.com/sxyazi/yazi/blob/84d71bfa397f2a217ca06c0651984ce1fb3b2507/yazi-plugin/src/loader/loader.rs#L58-L81

Sure(^^♪ I will fix it

Fix patch:
diff --git a/scripts/validate-form/main.js b/scripts/validate-form/main.js
index cd27c9e2c..45362ff21 100644
--- a/scripts/validate-form/main.js
+++ b/scripts/validate-form/main.js
@@ -12,7 +12,7 @@ function bugReportBody(creator, content, hash) {
 
 - The bug can still be reproduced on the [newest nightly build](https://yazi-rs.github.io/docs/installation/#binaries).
 - The debug information (\`yazi --debug\`) is updated for the newest nightly.
-- All *required* fields in the checklist have been checked.
+- The *required* fields in the checklist are checked.
 
 Issues with \`${LABEL_NAME}\` will be marked ready once edited with the proper content, or closed after 2 days of inactivity.
 `
@@ -27,7 +27,7 @@ function featureRequestBody(creator, content) {
 
 - The requested feature does not exist in the [newest nightly build](https://yazi-rs.github.io/docs/installation/#binaries).
 - The debug information (\`yazi --debug\`) is updated for the newest nightly.
-- All *required* fields in the checklist have been checked.
+- The *required* fields in the checklist are checked.
 
 Issues with \`${LABEL_NAME}\` will be marked ready once edited with the proper content, or closed after 2 days of inactivity.
 `
diff --git a/yazi-plugin/src/loader/loader.rs b/yazi-plugin/src/loader/loader.rs
index 99dcb43ac..d4cbbaae9 100644
--- a/yazi-plugin/src/loader/loader.rs
+++ b/yazi-plugin/src/loader/loader.rs
@@ -56,26 +56,34 @@ impl Loader {
 		}
 
 		// TODO: remove this
+		fn warn(name: &str) {
+			static WARNED: std::sync::atomic::AtomicBool = std::sync::atomic::AtomicBool::new(false);
+			if !WARNED.swap(true, std::sync::atomic::Ordering::Relaxed) {
+				yazi_proxy::AppProxy::notify(yazi_proxy::options::NotifyOpt {
+								title:   "Deprecated entry file".to_owned(),
+								content: format!(
+									"The plugin's entry file `init.lua` has been deprecated in favor of the new `main.lua` (user's own `init.lua` remains unchanged).
+
+Please run `ya pack -m` to automatically migrate all plugins, or manually rename your `{name}.yazi/init.lua` to `{name}.yazi/main.lua`."
+								),
+								level:   yazi_proxy::options::NotifyLevel::Warn,
+								timeout: std::time::Duration::from_secs(25),
+							});
+			}
+		}
+
 		let p = BOOT.plugin_dir.join(format!("{name}.yazi/main.lua"));
 		let chunk = match fs::read(&p).await {
 			Ok(b) => b,
 			Err(e) if e.kind() == std::io::ErrorKind::NotFound => {
-				static WARNED: std::sync::atomic::AtomicBool = std::sync::atomic::AtomicBool::new(false);
-				if !WARNED.swap(true, std::sync::atomic::Ordering::Relaxed) {
-					yazi_proxy::AppProxy::notify(yazi_proxy::options::NotifyOpt {
-						title:   "Deprecated entry file".to_owned(),
-						content: format!(
-							"The plugin's entry file `init.lua` has been deprecated in favor of the new `main.lua` (user's own `init.lua` remains unchanged).
-
-Please run `ya pack -m` to automatically migrate all plugins, or manually rename your `{name}.yazi/init.lua` to `{name}.yazi/main.lua`."
-						),
-						level:   yazi_proxy::options::NotifyLevel::Warn,
-						timeout: std::time::Duration::from_secs(25),
-					});
-				}
-
 				let p = BOOT.plugin_dir.join(format!("{name}.yazi/init.lua"));
-				fs::read(&p).await.with_context(|| format!("Failed to load plugin from {p:?}"))?
+				match fs::read(&p).await {
+					Ok(b) => {
+						warn(name);
+						b
+					}
+					Err(e) => Err(e).with_context(|| format!("Failed to load plugin from {p:?}"))?,
+				}
 			}
 			Err(e) => Err(e).with_context(|| format!("Failed to load plugin from {p:?}"))?,
 		};


Test patch: