jlcodes99/cockpit-tools · error

[Wakeup] 网关轨迹持续错误且未恢复: cascade_id={}, last_status={}, error_

Error message

[Wakeup] 网关轨迹持续错误且未恢复: cascade_id={}, last_status={}, error_code={:?}, message={}

What it means

During the gateway wakeup cascade, the client polls a status/trajectory endpoint; if errors persist across the trajectory without recovery, it aborts with '[Wakeup] 网关轨迹持续错误且未恢复: cascade_id=..., last_status=..., error_code=..., message=...'. This reports the gateway-side run stuck in an error state — not a client request failure but a persisted remote execution error surfaced with the last known status and error code.

Source

Thrown at src-tauri/src/modules/wakeup.rs:1619

                        cascade_id,
                        if last_status.is_empty() { "-" } else { &last_status },
                        err.error_code,
                        err.message,
                        err.error_message_json.len()
                    ));
                }
                return Err(encode_wakeup_ui_error_payload(&err));
            }

            sleep_with_cancel(
                std::time::Duration::from_millis(CLIENT_GATEWAY_POLL_INTERVAL_MS),
                cancel_rx,
            )
            .await?;
        }

        if let Some(err) = last_running_error {
            crate::modules::logger::log_error(&format!(
                "[Wakeup] 网关轨迹持续错误且未恢复: cascade_id={}, last_status={}, error_code={:?}, message={}",
                cascade_id,
                if last_status.is_empty() { "-" } else { &last_status },
                err.error_code,
                truncate_log_text(&err.message, 500)
            ));
            return Err(encode_wakeup_ui_error_payload(&err));
        }

        let message = if last_status.is_empty() {
            "网关未返回唤醒结果(轨迹中未出现 plannerResponse.modifiedResponse)".to_string()
        } else {
            format!("网关未在超时时间内返回唤醒结果,最后状态={}", last_status)
        };
        crate::modules::logger::log_error(&format!(
            "[Wakeup] 网关唤醒失败(超时/无结果): cascade_id={}, error={}",
            cascade_id, message
        ));

View on GitHub (pinned to 1ed8b77992)

Solutions

  1. Read error_code and last_status in the message — they identify the remote failure reason
  2. Retry the wakeup later to get a fresh cascade_id; do not reuse the errored cascade
  3. Verify account quota/permissions if the error_code indicates limits or denial
  4. Check gateway/service status for an ongoing outage
  5. Escalate with cascade_id and truncated message to the gateway operators if persistent

Example fix

// before
if let Some(err) = last_running_error {
    crate::modules::logger::log_error(&format!(
        "[Wakeup] 网关轨迹持续错误且未恢复: cascade_id={}, last_status={}, error_code={:?}, message={}", ...));
// after
if let Some(err) = last_running_error {
    crate::modules::logger::log_error(&format!(
        "[Wakeup] 网关轨迹持续错误且未恢复: cascade_id={}, last_status={}, error_code={:?}, message={}", ...));
    mark_cascade_failed(&cascade_id, &err); // persist for UI + telemetry
}
Defensive patterns

Strategy: try-catch

Validate before calling

// Before triggering, check no orphaned/failed cascade exists for this context
if let Some(prev) = last_cascade_for_context(ctx) {
    if prev.is_failed() && prev.age() < cooldown {
        eprintln!("previous cascade {} still failing; backing off", prev.id);
    }
}

Type guard

struct GatewayTrajectoryError { cascade_id: String, last_status: String, error_code: Option<String>, message: String }
fn is_persistent_trajectory_error(err: &str) -> bool { err.contains("网关轨迹持续错误且未恢复") }

Try / catch

match trigger_wakeup_via_client_gateway(req).await {
    Err(e) if e.contains("网关轨迹持续错误且未恢复") => {
        let cascade_id = extract_field(&e, "cascade_id=");
        // surface to UI with cascade_id; back off before starting a new cascade
        report_persistent_failure(cascade_id, &e);
        schedule_retry_with_backoff(Duration::from_secs(300));
    }
    other => handle(other),
}

Prevention

When it happens

Trigger: trigger_wakeup_via_client_gateway_once tracks a cascade_id's trajectory; each poll returns an error status/error_code, and after the recovery/retry budget is exhausted last_running_error is still Some, so the function logs and returns this error.

Common situations: Remote session failing to start (bad environment, missing sandbox); gateway dependency outage keeping the cascade in error; quota/account limit making every attempt fail; a bug in the requested operation causing deterministic failure; operator restarting services mid-run leaving orphaned cascades.

Related errors


AI-assisted analysis of jlcodes99/cockpit-tools@1ed8b77992 (2026-09-05). Data as JSON: /api/errors/7afc821c79d45edf. Report an issue: GitHub.