Native builds: a horizon-mixins error starts with the mod that doesn't apply

A player's native build on 2026-11-04 failed with "horizon-mixins failed
(exit status: 1)" on Horizon 998b1d8, the commit fast_items 0.1.0 pins.
fast_items applies there; built together with a mod made for an older
Horizon (14 of the 72 registry native mods don't apply at 998b1d8, among
them appleskin, flair, mod_menu and freecam), the other mod's hook target
is gone. The diagnostic named that mod only deep in a file path. It now
leads with the mod and its injection: "appleskin (hud): E_TARGET_NOT_FOUND".

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
Ludovic MarieandClaude Opus 5.5 committed 2026-11-04 19:00:22 +01:00
1 parent 795024bfc4
commit b5c41f49d8
1 file changed
+34 -2
+34 -2
View File
@@ -1560,12 +1560,19 @@ fn failure(what: &str, status: &str, errors: &[String], tail: &[String]) -> Stri
)
}
/// A horizon-mixins diagnostic (`{"code", "message", "file"}`) in one line.
/// A horizon-mixins diagnostic (`{"code", "message", "file"}`) in one line, led by the mod it
/// names (`mod_id`, and its `injection_id`), so a player with several mods sees which one
/// doesn't apply to the build's Horizon: their files' paths are deep in the launcher's folder.
fn diagnostic(text: &str) -> Option<String> {
let start = text.find('{')?;
let value: serde_json::Value = serde_json::from_str(&text[start..]).ok()?;
let culprit = match (value["mod_id"].as_str(), value["injection_id"].as_str()) {
(Some(m), Some(i)) => format!("{m} ({i}): "),
(Some(m), None) => format!("{m}: "),
_ => String::new(),
};
let mut line = format!(
"{}: {}",
"{culprit}{}: {}",
value["code"].as_str()?,
value["message"].as_str()?
);
@@ -4096,6 +4103,31 @@ mod tests {
);
}
#[test]
fn a_tool_error_starts_with_the_mod_that_does_not_apply() {
// horizon-mixins e8cd0aa on Horizon 998b1d8 with fast_items 0.1.0 and appleskin 1.0.0
// (made for ba6344a), as a player's build was on 2026-11-04.
let err = r#"{
"code": "E_TARGET_NOT_FOUND",
"message": "no source function 'horizon_client::game::titles::Game<'_>::draw_titles'",
"file": "/home/p/.local/share/horizon-launcher/native/mixins.incoming/appleskin/horizon-mixin.toml",
"mod_id": "appleskin",
"injection_id": "hud",
"target": "horizon_client::game::titles::Game<'_>::draw_titles"
}"#;
let line = diagnostic(err).unwrap();
assert!(
line.starts_with("appleskin (hud): E_TARGET_NOT_FOUND: no source function"),
"{line}"
);
// About a whole mod, no injection in it.
let err = r#"{"code": "E_REVISION", "message": "pinned to a", "mod_id": "chop"}"#;
assert_eq!(
diagnostic(err).as_deref(),
Some("chop: E_REVISION: pinned to a")
);
}
#[test]
fn a_failed_build_names_the_crate_its_output_pushed_out() {
// cargo's output on Linux without ALSA's development files (Rust 1.99.1, 2026-10-31):