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

  1. Reconnect/pair the device so the selected route exists in the paired inventory, then retry
  2. Re-run target selection so a route that actually exists in the current inventory is chosen (don't pass a hardcoded route)
  3. Verify with `openlogi list` that the target device is paired and has model info before contributing
  4. 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

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


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)