AprilNEA/OpenLogi · error
selected profile route has no identity-bearing device model
Error message
selected profile route has no identity-bearing device model
What it means
`selected_model` resolves the `DeviceModelInfo` for the profile route the user selected during fixture contribution. It walks the agent inventory looking for a paired device whose route matches the selected profile route, then extracts its identity-bearing model info. If no paired device matches (or the match has no `model_info`), it throws because a cassette relationship needs a real device identity behind the chosen route.
Solutions
- Reconnect/pair the device so the selected route exists in the paired inventory, then retry
- Re-run target selection so a route that actually exists in the current inventory is chosen (don't pass a hardcoded route)
- Verify with `openlogi list` that the target device is paired and has model info before contributing
- Regenerate the cassette/profile against the current device instead of reusing a stale one
Example fix
// before openlogi fixture contribute --route 'bolt:<old-uid>:3' // after openlogi list # confirm the device's current route/slot openlogi fixture contribute --route '<current route from openlogi list>'
Defensive patterns
Strategy: validation
Validate before calling
// before contributing, confirm the route resolves to a paired device with model info
let matches: Vec<_> = inventory.paired.iter()
.filter(|d| DeviceRoute::device_route_for(inventory, d.slot).as_ref() == Some(&route))
.collect();
if matches.len() != 1 || matches[0].model_info.is_none() {
eprintln!("route {route:?} has no single paired identity-bearing device; re-select target");
} Try / catch
match selected_model(inventory, &route) {
Ok(model) => proceed(model),
Err(e) => eprintln!("{e:#}; run `openlogi list` and re-select the device"),
} Prevention
- Run `openlogi list` and confirm the device is paired before contributing
- Never hardcode routes across sessions — slots and receiver UIDs change on re-pair
- Refresh the inventory snapshot immediately before selection
- Re-record rather than reusing cassettes from a different machine/receiver
When it happens
Trigger: Calling the fixture-contribute flow with a profile route that no currently paired device in the inventory carries — e.g. the profile was recorded against a device that has since been unpaired, moved to a different slot/receiver, or the inventory came back without that device paired.
Common situations: Running `openlogi fixture contribute` after unplugging the receiver, re-pairing the device (new slot), reusing a cassette recorded on another machine, or a stale agent snapshot where the target device is listed as offline/not paired.
Understand the failure class
Background: "Not found" and "does not exist" errors: why "Task not found", "No such folder", and "Can't find" fire when a lookup comes back empty — this error's family across 14 libraries.
Related errors
- --name must not be empty
- --channel must not be empty
- --id must be a nonempty synthetic identifier
- --name must be a nonempty synthetic profile name
- no addressable physical device candidate was found
AI-assisted analysis of AprilNEA/OpenLogi@e846e6f4b4 (2026-09-13).
Data as JSON: /api/errors/54346d73a2d2c980.
Report an issue: GitHub.
Appendix: source
Thrown at crates/openlogi-cli/src/cmd/fixture/contribute.rs:374
Ok(plan)
}
fn selected_model<'a>(
profile: &'a DeviceProfile,
route: &DeviceRoute,
slot: u8,
) -> Result<&'a DeviceModelInfo> {
profile
.inventories
.iter()
.find(|inventory| {
inventory.paired.iter().any(|device| {
DeviceRoute::device_route_for(inventory, device.slot).as_ref() == Some(route)
})
})
.and_then(|inventory| inventory.paired.iter().find(|device| device.slot == slot))
.and_then(|device| device.model_info.as_ref())
.ok_or_else(|| anyhow!("selected profile route has no identity-bearing device model"))
}
fn add_model_identities(plan: &mut HidCassetteIdentityPlan, model: &DeviceModelInfo) -> Result<()> {
if model.unit_id == [0; 4] && model.serial_number.is_none() {
bail!(
"the selected device has no stable synthetic identity for cassette relationships; \
rerun with --profile-only"
);
}
if model.unit_id != [0; 4] {
plan.insert(SanitizedIdentityKind::DeviceUnitId, model.unit_id.to_vec())?;
}
if let Some(serial) = model.serial_number.as_deref() {
plan.insert(
SanitizedIdentityKind::DeviceSerialNumber,
serial.as_bytes().to_vec(),
)?;
}View on GitHub (pinned to e846e6f4b4)