BigPizzaV3/CodexPlusPlus · error · anyhow::Error
Remote Control recovery requires profile and provider proven
Error message
Remote Control recovery requires profile and provider provenance
What it means
Second guard in validate_request (remote_control_recovery.rs): a pending recovery record must carry provenance — a non-blank profile_id and a non-blank target_provider. Without both fields the recovery queue entry could not be replayed to the right provider profile later, so persistence is refused up front.
Source
Thrown at crates/codex-plus-core/src/remote_control_recovery.rs:153
}
fn save_state(path: &Path, state: &PendingRemoteControlRecoveryState) -> anyhow::Result<()> {
if state.requests.is_empty() {
match std::fs::remove_file(path) {
Ok(()) => return Ok(()),
Err(error) if error.kind() == std::io::ErrorKind::NotFound => return Ok(()),
Err(error) => return Err(error.into()),
}
}
atomic_write(path, serde_json::to_string_pretty(state)?.as_bytes())
}
fn validate_request(request: &PendingRemoteControlRecovery) -> anyhow::Result<()> {
if request.thread_id.trim().is_empty() || request.thread_id.len() > 128 {
anyhow::bail!("Remote Control recovery requires a valid thread id");
}
if request.profile_id.trim().is_empty() || request.target_provider.trim().is_empty() {
anyhow::bail!("Remote Control recovery requires profile and provider provenance");
}
Ok(())
}
#[cfg(test)]
mod tests {
use super::*;
use tempfile::tempdir;
fn request(thread_id: &str) -> PendingRemoteControlRecovery {
PendingRemoteControlRecovery {
thread_id: thread_id.to_string(),
profile_id: "official-mix".to_string(),
target_provider: "custom".to_string(),
config_generation: "generation".to_string(),
created_at: 1,
}
}View on GitHub (pinned to 1f431ae49b)
Solutions
- Populate profile_id with the active RelayProfile.id and target_provider with the provider name before recording the pending recovery
- Defer recording until both settings and active profile are loaded
- Fix the fixture/test to include provenance fields
- Log the record fields at the call site when validation fails to catch silent empty strings
Example fix
// before
PendingRemoteControlRecovery {
thread_id: tid.clone(),
profile_id: String::new(),
target_provider: String::new(),
// ...
}
// after
PendingRemoteControlRecovery {
thread_id: tid.clone(),
profile_id: settings.active_relay_profile().id.to_string(),
target_provider: settings.active_relay_profile().name.clone(),
// ...
} Defensive patterns
Strategy: validation
Validate before calling
if request.profile_id.trim().is_empty() || request.target_provider.trim().is_empty() {
// defer recording until settings + active profile are loaded
return Ok(());
} Type guard
fn has_provenance(r: &PendingRemoteControlRecovery) -> bool {
!r.profile_id.trim().is_empty() && !r.target_provider.trim().is_empty()
} Try / catch
match record_pending_remote_control_recovery(path, req) {
Err(e) if e.to_string().contains("provenance") => { /* re-enqueue after profile load */ }
other => other?,
} Prevention
- Capture provenance at the same moment the recovery is triggered, from the same settings snapshot
- Never build PendingRemoteControlRecovery from default::default()
- Add a serde default + post-load assertion so missing fields fail loudly in tests
When it happens
Trigger: Calling record_pending_remote_control_recovery with a PendingRemoteControlRecovery whose profile_id.trim() or target_provider.trim() is empty — e.g. the frontend built the record before the active profile was loaded, or the provider name field was never populated for a hand-written profile.
Common situations: Race where the recovery record is captured during startup before settings finish loading; a test fixture that only sets thread_id; a profile created without a provider label; null coerced to empty string through JSON deserialization.
Related errors
- Remote Control recovery requires a valid thread id
- 中转 Key 不能为空
- config.toml 内容不能为空
- {label}必须大于 0
- Remote Control session recovery is unavailable
AI-assisted analysis of BigPizzaV3/CodexPlusPlus@1f431ae49b (2026-08-16).
Data as JSON: /api/errors/8e5c620aa8ce897e.
Report an issue: GitHub.