libnyanpasu/clash-nyanpasu · error

failed to parse config to yaml file

Error message

failed to parse config to yaml file

What it means

get_runtime_yaml fetches the promoted runtime config state from NyanpasuClient and serializes it to YAML. If there is no promoted runtime state yet, the ok_or on the None Option produces this error before serialization is attempted. Despite the message, the failure is a missing runtime snapshot, not a YAML parsing problem.

Solutions

  1. Activate/select a profile so the runtime config is generated, then retry.
  2. Trigger a config refresh (reapply the profile or restart the core).
  3. Check logs for an earlier runtime-config build failure and fix that root cause.
  4. Improve the error to distinguish 'no runtime state' from conversion failure.

Example fix

// before
.ok_or(anyhow::anyhow!("failed to parse config to yaml file"))
// after
.ok_or(anyhow::anyhow!("no runtime config has been generated yet"))
Defensive patterns

Strategy: try-catch

Try / catch

try {
  const yaml = await invoke('get_runtime_yaml');
} catch (e) {
  if (String(e).includes('failed to parse config to yaml')) {
    showEmptyRuntimeState(); // no profile activated yet
  } else throw e;
}

Prevention

When it happens

Trigger: Calling the get_runtime_yaml IPC command before any profile has been activated or after a failed config update left no promoted runtime state.

Common situations: Fresh install with no profile selected, first launch before core startup, or a previous runtime-config build failure so promoted_runtime() returns None.

Understand the failure class

Background: "missing required config value" errors: why libraries refuse to start when a configuration key is empty, unset, or blank — this error's family across 48 libraries.

Related errors


AI-assisted analysis of libnyanpasu/clash-nyanpasu@f7dbce2997 (2026-09-08). Data as JSON: /api/errors/ace7d0cbfd322859. Report an issue: GitHub.

Appendix: source

Thrown at backend/tauri/src/ipc.rs:363

        Some(state) => {
            let yaml_value = serde_yaml::to_value(&state.config)?;
            let json_value = serde_json::to_value(&yaml_value)?;
            let wrapped: specta_typescript::Any<serde_json::Value> =
                serde_json::from_value(json_value)?;
            Ok(Some(wrapped))
        }
        None => Ok(None),
    }
}

#[tauri::command]
#[specta::specta]
pub async fn get_runtime_yaml(client: State<'_, NyanpasuClient>) -> Result<String> {
    let state = client.promoted_runtime().await;
    let mapping = (state
        .as_ref()
        .map(|state| &state.config)
        .ok_or(anyhow::anyhow!("failed to parse config to yaml file"))
        .and_then(|config| {
            serde_yaml::to_string(config).context("failed to convert config to yaml")
        }))?;
    Ok(mapping)
}

#[tauri::command]
#[specta::specta]
pub async fn inspect_runtime(
    client: State<'_, NyanpasuClient>,
) -> Result<Option<crate::client::runtime_inspection::RuntimeInspection>> {
    Ok(client.inspect_runtime().await)
}

#[tauri::command]
#[specta::specta]
pub async fn inspect_runtime_node(
    client: State<'_, NyanpasuClient>,

View on GitHub (pinned to f7dbce2997)