BigPizzaV3/CodexPlusPlus · error · anyhow::Error
Remote Control session recovery requires launcher hooks…
Error message
Remote Control session recovery requires launcher hooks with codex-plus-data integration
What it means
This stub throws because Remote Control session recovery is not implemented in the launcher-holes-less build: `run_remote_control_session_recovery` is intentionally a `bail!` placeholder that documents the missing integration with the codex-plus-data persistence layer. Callers invoke it expecting session recovery, but the launcher binary was built without the data-layer hooks that store/restore session state. It is a guard against silently running recovery with no backend.
Solutions
- Build/wire the launcher with codex-plus-data integration enabled (enable the relevant feature/wiring so the stub is replaced by the real implementation)
- Check the call site: only invoke Remote Control session recovery when hooks are installed, or feature-gate the command in the UI/CLI
- Upgrade to a launcher build/version where the hook implementation is present
Example fix
// before
async fn run_remote_control_session_recovery(&self) -> anyhow::Result<()> {
anyhow::bail!("Remote Control session recovery requires launcher hooks with codex-plus-data integration")
}
// after
async fn run_remote_control_session_recovery(&self) -> anyhow::Result<()> {
let data = self.codex_plus_data().ok_or_else(|| anyhow::anyhow!("launcher hooks not installed"))?;
data.recover_remote_control_sessions().await
} Defensive patterns
Strategy: try-catch
Validate before calling
// Rust: check hook availability before invoking
if !launcher.has_codex_plus_data_hooks() {
return Err(anyhow::anyhow!("Remote Control recovery unavailable: data hooks not installed"));
} Type guard
fn hooks_installed(l: &Launcher) -> bool { l.codex_plus_data_handle().is_some() } Try / catch
match launcher.run_remote_control_session_recovery().await {
Ok(()) => {},
Err(e) if e.to_string().contains("launcher hooks") => eprintln!("recovery unavailable in this build: {e}"),
Err(e) => return Err(e),
} Prevention
- Feature-gate recovery commands in UI/CLI by build features
- Detect the stub message and surface an actionable install/upgrade hint to users
- Add a capabilities() probe API so callers can query support before calling
When it happens
Trigger: Any call path that reaches `run_remote_control_session_recovery` (e.g. CLI subcommand or manager UI invoking Remote Control recovery) when the launcher is compiled/wired without codex-plus-data integration.
Common situations: Running a slim/headless build of codex-plus-manager; using a stale launcher binary built before the data integration was enabled; invoking the recovery routine from a harness that did not install launcher hooks.
Understand the failure class
Background: "not installed", "pip install", "required for": how missing-dependency errors surface across open-source libraries — this error's family across 34 libraries.
Related errors
- archived lookup task failed
- built-in Dream Skin theme cannot be deleted
- built-in Dream Skin theme is read-only
- cannot terminate Windows process id
- cannot wait for Windows process id
AI-assisted analysis of BigPizzaV3/CodexPlusPlus@b1ed92e5e4 (2026-09-19).
Data as JSON: /api/errors/bad9773c00fd8c74.
Report an issue: GitHub.
Appendix: source
Thrown at crates/codex-plus-core/src/launcher.rs:715
crate::ports::select_platform_loopback_port(requested)
}
async fn load_settings(&self) -> anyhow::Result<BackendSettings> {
SettingsStore::default().load()
}
fn cleanup_unsupported_config(&self) -> anyhow::Result<()> {
let home = crate::relay_config::default_codex_home_dir();
crate::relay_config::cleanup_unsupported_approval_policies_in_home(&home)?;
Ok(())
}
async fn run_provider_sync(&self) -> anyhow::Result<()> {
anyhow::bail!("provider sync requires launcher hooks with codex-plus-data integration")
}
async fn run_remote_control_session_recovery(&self) -> anyhow::Result<()> {
anyhow::bail!(
"Remote Control session recovery requires launcher hooks with codex-plus-data integration"
)
}
fn remote_control_session_recovery_is_safe_to_run(&self) -> bool {
crate::watcher::find_session_index_cleanup_blocking_processes().is_empty()
}
async fn apply_active_relay_profile(&self, settings: &BackendSettings) -> anyhow::Result<()> {
if !settings.relay_profiles_enabled {
return Ok(());
}
let profile = settings.active_relay_profile();
let home = crate::relay_config::default_codex_home_dir();
let common_config = crate::relay_config::normalize_config_text(
&[
settings.relay_common_config_contents.as_str(),
settings.relay_context_config_contents.as_str(),View on GitHub (pinned to b1ed92e5e4)