libnyanpasu/clash-nyanpasu · info
[mutation-degradation]
Error message
[mutation-degradation]
What it means
The MutationDegradationNotifier component in the root route observes mutation-degradation events emitted by the state/config layer — cases where a mutation was applied but some post-commit side effect failed and the system degraded gracefully. For each degradation it logs a console.warn with phase, code, retryable, and message; the backend's message field is diagnostic-only, the primary copy is phase + code. This is a diagnostic log, not a thrown error.
Source
Thrown at frontend/nyanpasu/src/pages/__root.tsx:188
return m.mutation_degraded_item({
phase: localizeDegradationPhase(degradation.phase),
detail: localizeDegradationCode(degradation.code),
})
}
function MutationDegradationNotifier() {
useEffect(
() =>
// setMutationDegradationHandler returns a disposer; useEffect cleanup
// passes it through so StrictMode remount / HMR leave no dangling handler.
setMutationDegradationHandler((degradations) => {
if (degradations.length === 0) {
return
}
// Backend `message` is diagnostic-only; primary copy is phase + code.
for (const degradation of degradations) {
console.warn('[mutation-degradation]', {
phase: degradation.phase,
code: degradation.code,
retryable: degradation.retryable,
message: degradation.message,
})
}
const items = degradations.map(formatDegradationItem).join('; ')
message(m.mutation_degraded_summary({ items }), {
title: m.mutation_degraded_title(),
kind: 'warning',
}).catch((error) => {
console.error('[mutation-degradation] failed to show warning', error)
})
}),
[],
)
return nullView on GitHub (pinned to f7dbce2997)
Solutions
- Read the logged `phase` and `code` fields — they identify which post-commit side effect degraded and why.
- If `retryable` is true, retry the mutation or trigger the affected action (e.g. restart core) — transient side-effect failures often succeed on retry.
- If not retryable, fix the underlying condition indicated by the code (e.g. invalid runtime config, missing core binary) and re-apply the change.
- Use the `message` field only as diagnostic detail; rely on phase + code for user-facing copy and triage.
Example fix
// before: ignoring degradations silently
await client.patch_app_config(patch);
// after: check result and handle degraded side effects
const result = await client.patch_app_config(patch);
if (result.degradations.some(d => d.retryable)) {
await client.restart_core().catch(reportDegraded);
} Defensive patterns
Strategy: retry
Try / catch
try {
await client.patch_app_config(patch);
} catch (e) {
if (e.degradations?.some(d => d.retryable)) {
await client.restart_core(); // retry the degraded side effect
} else {
throw e;
}
} Prevention
- After any config mutation, check for degradation entries and act on non-empty phase/code pairs.
- Retry retryable degradations (e.g. restart core) instead of leaving stale runtime config.
- Treat backend `message` as diagnostic-only; alert users with phase + code copy.
- Monitor these warnings in logs to catch recurring side-effect failures (core binary missing, IPC timeouts).
When it happens
Trigger: A config/profile patch mutation committed but a post-commit side effect (e.g. core restart, runtime config regeneration, tray/UI notification) failed; the backend reports a degradation entry with a phase, a code, and a retryable flag, and the notifier logs it.
Common situations: Core process fails to restart after a config change; a side effect times out after a config patch; transient IPC errors while saving profile changes. Users see degraded behavior (stale runtime config) while persisted state is fine.
Understand the failure class
Background: "invalid response format", "malformed payload", "missing data field": when an API returns 200 but the response shape is wrong — this error's family across 23 libraries.
Related errors
- proxy selection succeeded; connection interruption error: {:
- remove index invalid, skipped
- Function is locked: ${fnRef.current.name}
- Proxy addEventListener:
AI-assisted analysis of libnyanpasu/clash-nyanpasu@f7dbce2997 (2026-09-08).
Data as JSON: /api/errors/3e1eca013ac47456.
Report an issue: GitHub.