libnyanpasu/clash-nyanpasu · error
prepare() called more than once with different identifiers.
Error message
prepare() called more than once with different identifiers.
What it means
prepare() stores the deep-link plugin identifier in a OnceCell that can only be set once. If prepare() is called a second time with a different identifier than the first call, ID.set() returns Err and this expect() panics. The library uses this to guarantee a single, consistent per-app identifier for IPC socket paths.
Source
Thrown at backend/tauri-plugin-deep-link/src/linux.rs:156
if let Err(io_err) =
stream.write_all(std::env::args().nth(1).unwrap_or_default().as_bytes())
{
log::error!(
"Error sending message to primary instance: {}",
io_err.to_string()
);
};
std::process::exit(0);
}
Err(err) => {
log::error!("Error creating socket listener: {}", err.to_string());
if err.kind() == ErrorKind::ConnectionRefused {
let _ = remove_file(&addr);
}
}
};
ID.set(identifier.to_string())
.expect("prepare() called more than once with different identifiers.");
}
View on GitHub (pinned to f7dbce2997)
Solutions
- Call prepare() exactly once per process, early in the app entry point
- Use the same identifier string on every call (derive it from a single constant/config)
- If re-initialization is required, run it in a fresh process instead of calling prepare() again
- Guard with Once: use a wrapper that only forwards the first prepare() call
Example fix
// before
prepare("com.app.dev");
// ...
prepare("com.app.test"); // panics
// after
const IDENTIFIER: &str = "com.app.dev";
prepare(IDENTIFIER); // called once, from one place Defensive patterns
Strategy: validation
Validate before calling
if ID.get().map(|id| id.as_str()) == Some(identifier) { return; } // skip duplicate prepare with same id
assert!(ID.get().is_none(), "prepare() already called"); Type guard
fn is_prepared() -> bool { ID.get().is_some() } Prevention
- Call prepare() once, in a single bootstrap location
- Derive the identifier from one shared constant
- Avoid re-running app setup in the same process
When it happens
Trigger: Calling prepare(identifier) twice in one process with different identifier strings, e.g. during app re-initialization, hot-reload of the Tauri setup hook, or two test cases reusing one process with different bundle IDs.
Common situations: Dev hot-reload rebuilding the Tauri app state without restarting the process; test harnesses calling prepare() per test with a distinct identifier; accidentally invoking prepare() in both a plugin init hook and the app setup closure.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- URL event received before prepare() was called
- listen() called before prepare()
- prepare() called more than once with different identifiers.
- register() called before prepare()
- listen() called before prepare()
AI-assisted analysis of libnyanpasu/clash-nyanpasu@f7dbce2997 (2026-09-08).
Data as JSON: /api/errors/fe4a8410c2727ebf.
Report an issue: GitHub.