ruvnet/ruflo · error · Error
Pairing failed for device ${device.deviceId}
Error message
Pairing failed for device ${device.deviceId} What it means
DeviceLifecycleService.pairDevice calls the device SDK's pair.create() and expects result.paired === true; a structured false result is converted into this exception. It indicates the pairing protocol ran but the device did not confirm pairing — distinct from transport errors, which the SDK would raise itself.
Source
Thrown at v3/@claude-flow/plugin-iot-cognitum/src/domain/services/device-lifecycle-service.ts:116
endpoint,
metadata: {},
};
this.deps.onDeviceRegistered?.(device);
return device;
}
/**
* Pair a device using the SDK's pair.create() and promote its trust level.
*/
async pairDevice(
device: DeviceAgent,
clientName: string,
): Promise<DeviceAgent> {
const result = await this.deps.pairDevice(device.deviceId, clientName);
if (!result.paired) {
throw new Error(`Pairing failed for device ${device.deviceId}`);
}
const oldLevel = device.trustLevel;
const newLevel =
device.trustLevel < DeviceTrustLevel.PROVISIONED
? DeviceTrustLevel.PROVISIONED
: device.trustLevel;
const updated: DeviceAgent = {
...device,
trustLevel: newLevel,
trustScore: {
...device.trustScore,
overall: this.computeTrustScore(device, 0, 0, true).overall,
components: {
...device.trustScore.components,
pairingIntegrity: 1.0,
},View on GitHub (pinned to fa13ee4ad6)
Solutions
- Verify the device is powered, online, and in pairing mode, then restart the pair flow from the beginning
- Check the SDK logs or device endpoint for the underlying refusal reason (timeout, confirmation mismatch)
- If an earlier partial pairing left state behind, reset or unregister the device and re-pair
Example fix
// before
const updated = await lifecycle.pairDevice(device, 'gateway-1'); // paired=false -> throws
// after
const probe = await sdkPair(device.deviceId, 'gateway-1');
if (!probe.paired) {
logger.warn(`pair refused for ${device.deviceId}; keeping trust level ${device.trustLevel}`);
} else {
const updated = await lifecycle.pairDevice(device, 'gateway-1');
} Defensive patterns
Strategy: try-catch
Validate before calling
const reachable = await pingDevice(device.endpoint);
if (!reachable) {
throw new Error(`device ${device.deviceId} unreachable; skip pairing attempt`);
}
return lifecycle.pairDevice(device, clientName); Try / catch
for (let attempt = 1; attempt <= 3; attempt++) {
try {
return await lifecycle.pairDevice(device, clientName);
} catch (e) {
if (e instanceof Error && e.message.startsWith('Pairing failed for device ')) {
await sleep(backoff(attempt)); // device may still be in pairing mode
continue;
}
throw e;
}
}
throw new Error('pairing retries exhausted'); Prevention
- Confirm the device is powered, online, and in pairing mode before invoking pairDevice
- Restart the full pairing flow on refusal instead of half-promoting trust
- Log the SDK pair result reason to distinguish refusals from crashes
When it happens
Trigger: Pairing a device that is offline or at the wrong endpoint; the device's pairing window or confirmation step expired; trust/credential mismatch between coordinator and Seed device; SDK returning paired:false for a busy device.
Common situations: Provisioning lines where the device was power-cycled mid-flow; long delays between initiating and confirming pairing; retrying pairing after a partially completed earlier attempt.
Related errors
- Device ${deviceId} not registered with coordinator
- IoT Cognitum not initialized. Run "iot register" first.
- --vector must be a JSON array of numbers, got: ${raw}
- No vectors to ingest. Pass --vector "[..]" or pipe a JSON ar
- Cannot compute baseline from empty readings
AI-assisted analysis of ruvnet/ruflo@fa13ee4ad6 (2026-08-18).
Data as JSON: /api/errors/2cca87bf53afeacc.
Report an issue: GitHub.