Skip to content

Troubleshoot

This page is symptom-keyed: scan the table of contents for what you are seeing and follow the runbook.

Pairing fails

Symptom: Error: cloud endpoint unreachable

Cause: the --cloud URL is wrong, the cloud is down, or the local network blocks it.

Fix:

bash
curl -fsS https://hivecast.ai/healthz | jq .
# or for a sibling Host:
curl -fsS http://127.0.0.1:3100/healthz | jq .

If curl fails, the network is the problem. If curl succeeds but hivecast login still says unreachable, check that you are running the right hivecast binary (the wrapper or a stale dist). Re-build:

bash
pnpm --filter hivecast build

Symptom: User code never approves

Cause: the user did not click "Approve" within 30 minutes (DEVICE_LINK_DURATION_MS), or approved against a different account.

Fix: re-run hivecast login --device. If the URL the CLI printed leads nowhere, your --cloud may be wrong or pointing at a Host that doesn't have the Devices page exposed.

Symptom: Approval required: principal has no Space — claim a Space-path first

Cause: the principal that approved has no Space yet. The cloud's HostNamespaceStore.claim() won't fall through to a default Space if the principal has no namespaces and the device-code didn't include a routeKey.

Fix:

bash
hivecast login --device --cloud https://hivecast.ai \
  --route-key my-space-path

…or claim a Space-path in the cloud UI first, then retry without --route-key.

Heartbeats fail

Symptom: device.heartbeat.failed { reason: 'register-failed' }

Cause: system.devices.devices.register returned { ok: false }. Most common reason: the previous record's identity scope disagrees with the new payload (see Ownership).

Diagnose:

bash
matrix invoke system.devices devices.list \
  '{"principalId":"p_<sha20>","includeOffline":true}'

Look for a record with the same deviceId (== hostId) but a different principalId / spaceId / authorityRoot / hostLinkId.

Fix: if the existing record is stale (e.g. from a previous Space pairing), revoke it via auth.hostLink.revoke and re-pair. The record will be replaced once the previous Host Link is revoked.

Symptom: Cloud device heartbeat failed: HTTP 401

Cause: bearer token is wrong. Either rotation happened cloud-side without the Device picking up the new value, or the link was revoked.

Diagnose:

bash
hivecast link-status --home /tmp/matrix-home

Fix: if linked: true but heartbeat 401s, re-pair:

bash
hivecast logout --local-only --home /tmp/matrix-home
hivecast login --device --cloud <url> --home /tmp/matrix-home

Symptom: Cloud device heartbeat failed: HTTP 403

Cause: link exists but is revoked, or the body identity does not match the bearer-verified identity.

Fix: if the link is revoked, re-pair (see above). If body identity is wrong, the calling code is buggy: the heartbeat payload's principalId/authorityRoot must match the link the bearer token binds to. Inspect host.control's deviceHeartbeatPayload() against the live link; mismatches indicate corrupt hivecast-link.json.

Symptom: heartbeat succeeds but Device never appears in devices.list

Cause: the calling code's scope filter excludes the Device. Recall: a no-scope devices.list({}) returns ONLY no-scope Devices.

Fix: pass principalId (and optionally spaceId, authorityRoot):

bash
matrix invoke system.devices devices.list \
  '{"principalId":"p_<sha20>"}'

Or for "everything I have ever paired":

bash
matrix invoke system.devices devices.list \
  '{"principalId":"p_<sha20>","includeOffline":true}'

Linked but not running

Symptom: Device shows status: 'linked' instead of 'online'

Cause: the durable Host Link exists but no live presence record. The Device is paired but its host.control is not posting heartbeats.

Diagnose on the Device:

bash
hivecast status --home /tmp/matrix-home
hivecast link-status --home /tmp/matrix-home

If status shows the Host running but host.control is not in the runtime list, that's a runtime bootstrap problem — see the host-not-running troubleshoot in the docs-hivecast package.

If host.control is running but heartbeats are not firing, look for device.heartbeat.failed events on the bus (or the gateway's log files).

Inventory data looks wrong

Symptom: two Devices for one physical install

Cause: the same physical install paired multiple times under different Spaces, or with different routeKeys, producing distinct records. compactDeviceViews() collapses these when they share a stable installId, but pre-stable-installId records may persist.

Fix: inspect with includeOffline: true. If one record has a installId matching /^install_[a-f0-9]{20}$/ and the other does not, that's the legacy record. Revoke the legacy Host Link and the record will fade.

Symptom: Device renamed but deviceSlug unchanged

Expected behaviour. deviceSlug is stable per pairing. Renaming via hostName (--device-name) does not regenerate the slug. To get a new slug, re-pair with a different starting label.

Symptom: hostName field is empty

Possible cause: the link was created without --device-name and there is no legacy displayName to migrate from. The CLI should be re-run with --device-name <label>. Alternatively, set the label via a UI on the cloud Devices page (target state — currently fixed at pair time).

Cleaning up

If a Host's local credential files are corrupt and pairing keeps failing in confusing ways, hard-reset:

bash
hivecast logout --all --home /tmp/matrix-home
# verify
ls /tmp/matrix-home/credentials/
# should show no hivecast-* files

hivecast install --home /tmp/matrix-home   # mints a fresh installId
hivecast start --home /tmp/matrix-home
hivecast login --device --cloud <url> --home /tmp/matrix-home

Where to look in code

SymptomCode path
Pairing wire issuespackages/system-auth/src/host-auth.ts (HostDeviceLinkStore, HostLinkStore)
Heartbeat receiver issuespackages/system/src/SystemDevicesActor.ts
Heartbeat sender issuespackages/host-control/src/HostControlActor.ts
Local credential file corruptionpackages/mx-cli/src/utils/hivecast-link-store.ts
Identity / Space / Authority confusionWORKSTREAMS/core-and-packaging/MATRIX-AUTHORITY-MODEL.md

See also

  • Pair — clean pairing runbook.
  • Disconnect — and re-pair.
  • Inventory / Heartbeats — heartbeat contract.
  • WORKSTREAMS/loose-ends/items/P1.17-device-heartbeat-auth-proof.md — adversarial heartbeat scenarios.

Source: code references inline.