libnyanpasu/clash-nyanpasu · error · ClientError
legacy verge bridge is not managed
Error message
legacy verge bridge is not managed
What it means
Raised by `LegacyVergeBridge::managed()` when the bridge's optional `managed` field (`Option<...>`) is `None`, i.e. the bridge was constructed without being attached to a managed legacy verge store/client. Any operation that needs the managed inner (snapshot, get/patch verge config, run mutations) will fail with this error.
Source
Thrown at backend/tauri/src/bridge/verge.rs:356
fn legacy_mutation_partial(error: anyhow::Error, source: Option<ClientError>) -> ClientError {
let message = format!(
"legacy mutation may have non-reversible side effects and requires reconciliation: {error:#}"
);
if let Some(ClientError::PartialCommit(partial)) = source {
return partial.with_legacy_state_uncertain(message).into();
}
let primary = ClientError::Anyhow(error);
PartialCommit::new(&primary, Vec::new(), Vec::new(), Vec::new())
.with_legacy_state_uncertain(message)
.into()
}
fn managed(&self) -> ClientResult<&LegacyVergeBridgeInner> {
self.managed
.as_deref()
.ok_or_else(|| anyhow::anyhow!("legacy verge bridge is not managed").into())
}
async fn get_verge_config_unlocked(&self) -> ClientResult<IVerge> {
let managed = self.managed()?;
let app = managed.client.get_app_config().await?;
let session = managed.client.get_session_state().await?;
let clash = managed.client.get_clash_config().await?;
Ok(super::legacy_iverge_from_typed(
self.legacy_store.snapshot()?,
&app,
&session,
&clash,
)?)
}
async fn refresh_legacy_projection(&self) -> ClientResult<IVerge> {
let managed = self.managed()?;View on GitHub (pinned to f7dbce2997)
Solutions
- Ensure the app bootstrap/composition root constructs and attaches the managed inner before any command uses the bridge.
- Check initialization order: complete actor spawn and bridge setup before registering/serving Tauri commands.
- In tests, construct the bridge with a managed inner (test fixtures with injected fake clients) instead of the bare constructor.
- Add an early readiness check so commands return a clear 'not initialized' state rather than hitting this error.
Example fix
// before: bridge used before setup let bridge = LegacyVergeBridge::new(); bridge.get_verge_config().await?; // panics-free error: not managed // after: setup first, then use let bridge = LegacyVergeBridge::new(); bridge.attach_managed(client, legacy_verge_path).await?; // populate managed bridge.get_verge_config().await?;
Defensive patterns
Strategy: type-guard
Validate before calling
// guard before using the bridge
if !bridge.is_managed() {
return Err(ClientError::from(anyhow::anyhow!(
"verge bridge not initialized; complete bootstrap first"
)));
} Type guard
fn is_managed(bridge: &LegacyVergeBridge) -> bool {
bridge.managed_handle().is_some()
} Try / catch
match bridge.get_verge_config().await {
Err(e) if e.to_string().contains("not managed") => {
// bootstrap not finished; retry after initialization signal
bootstrap_ready.notified().await;
}
other => other?,
} Prevention
- Wire the bridge in the composition root before registering Tauri commands.
- Expose an explicit initialized/ready flag on the client facade.
- In tests, always construct the bridge with a managed inner fixture.
- Avoid making the managed dependency Optional in new code; inject it at construction.
When it happens
Trigger: Invoking any bridge operation (`patch_verge_config`, `get_verge_config`, `run_legacy_verge_mutation`, `replace_verge_config`) on a `LegacyVergeBridge` that was built without calling the setup that populates `self.managed` (e.g. used before bootstrap/`AppSupervisor` wired it, or in a context where the legacy bridge was intentionally disabled).
Common situations: Calling Tauri commands during app startup before the composition root has initialized the bridge; unit tests instantiating the bridge without a managed inner; a refactor making `managed` optional without guarding all call sites.
Understand the failure class
Background: "X is required", "must be set", "cannot be empty": the missing-required-config error family, from Vertex AI project/location to WeChat keys — this error's family across 18 libraries.
Related errors
- Shutdown hook already set
- failed to start download: {e}
- prepare() called more than once with different identifiers.
- URL event received before prepare() was called
- listen() called before prepare()
AI-assisted analysis of libnyanpasu/clash-nyanpasu@f7dbce2997 (2026-09-08).
Data as JSON: /api/errors/dc66ae243d64cd5c.
Report an issue: GitHub.