clash-verge-rev/clash-verge-rev · error · anyhow::Error
failed to configure Job Object for sidecar PID {pid}: {job_e
Error message
failed to configure Job Object for sidecar PID {pid}: {job_error:#}; failed to terminate child: {kill_error:#} What it means
Windows-only. After spawn succeeds, create_and_assign_sidecar_job(child.pid()) is called to put the sidecar into a Job Object with KILL_ON_JOB_CLOSE so it dies with the app. If Job Object assignment fails, the code attempts to clean up by child.kill(); if that kill ALSO fails, the two errors are combined into this bail and the readiness flow aborts. It is a compound failure: cannot manage the process AND cannot terminate it.
Source
Thrown at src-tauri/src/core/manager/state.rs:157
crate::core::owner_identity::current_user_pipe_sddl()?,
);
let (mut rx, child) = command.spawn().map_err(|error| {
anyhow::anyhow!(
"failed to start sidecar core {clash_core:?} with config {} and data directory {}: {error:#}",
config_file.display(),
config_dir.display()
)
})?;
#[cfg(target_os = "windows")]
let job = {
match create_and_assign_sidecar_job(child.pid()) {
Ok(job) => job,
Err(job_error) => {
let pid = child.pid();
let error = match child.kill() {
Ok(()) => job_error,
Err(kill_error) => anyhow::anyhow!(
"failed to configure Job Object for sidecar PID {pid}: \
{job_error:#}; failed to terminate child: {kill_error:#}"
),
};
logging!(error, Type::Core, "Failed to start sidecar: {error:#}");
return Err(error);
}
}
};
#[cfg(unix)]
unsafe {
tauri_plugin_clash_verge_sysinfo::libc::umask(previous_mask)
};
let pid = child.pid();
logging!(trace, Type::Core, "Sidecar started with PID: {}", pid);View on GitHub (pinned to 5cad0f2799)
Solutions
- Read job_error first — most often OpenProcess/AssignProcessToJobObject permission or nesting; run the app outside of job-constrained hosts (e.g. some CI/terminal job wrappers).
- Confirm the app (and its service, if elevated) has the necessary process rights to manage the sidecar PID.
- If reproducing in CI, disable nested-job restrictions or run the app directly rather than under a job-bearing shell.
- Check whether the sidecar crashed instantly — if so, fix the underlying crash and the compound error disappears.
Defensive patterns
Strategy: try-catch
Try / catch
match core_manager.start_core_by_sidecar().await {
Ok(_) => Ok(()),
Err(e) if e.to_string().contains("failed to configure Job Object") => {
// surface the windows job-assignment error; advise running outside job-constrained hosts
Err(e)
}
Err(e) => Err(e),
} Prevention
- Do not launch the app under a parent that places children in a non-nested Job Object.
- Grant the app/service the process rights needed to manage the sidecar PID.
- Investigate job_error first; the kill_error is downstream.
When it happens
Trigger: create_and_assign_sidecar_job returned an error (e.g. OpenProcess/AssignProcessToJobObject failed — permission denied, job nesting limits on older Windows, process already in a conflicting job), and immediately afterward child.kill() also returned an error (process already exited, handle invalid, access denied).
Common situations: Running the app under a parent process that already places children in a Job Object that disallows nested job assignment; antivirus injecting into the child so kill fails; the sidecar exited on its own in the microsecond between assign-attempt and kill so the handle is no longer valid.
Related errors
- {readiness_error:#}; failed to terminate unready sidecar PID
- Sidecar continuation is not allowed from {mode:?} / {status:
- Sidecar did not become ready
- Sidecar startup failed: {error:#}; failed to clear proxy bef
- Sidecar did not become ready after service uninstall
AI-assisted analysis of clash-verge-rev/clash-verge-rev@5cad0f2799 (2026-08-12).
Data as JSON: /api/errors/46915d226f8f9b17.
Report an issue: GitHub.