{"record":{"id":"42046a01c6a2b230","repo":"chenhg5/cc-connect","slug":"matrix-device-id-not-available","errorCode":null,"errorMessage":"matrix: device ID not available","messagePattern":"matrix: device ID not available","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"platform/matrix/verification.go","lineNumber":283,"sourceCode":"\tdoneContent := &event.VerificationDoneEventContent{}\n\tdoneContent.SetRelatesTo(&event.RelatesTo{Type: event.RelReference, EventID: id.EventID(txnID)})\n\tif _, err := client.SendMessageEvent(ctx, evt.RoomID, event.InRoomVerificationDone, &event.Content{Parsed: doneContent}); err != nil {\n\t\tslog.Error(\"matrix: failed to send verification done\", \"error\", err)\n\t}\n\n\t// Clean up the transaction\n\thelper := p.getVerificationHelper()\n\tif helper != nil {\n\t\t_ = helper.DismissVerification(ctx, txnID)\n\t}\n\tslog.Info(\"matrix: verification complete\", \"txn_id\", txnID)\n}\n\n// crossSigningSeedsPath returns the path where cross-signing seeds are persisted.\nfunc (p *Platform) crossSigningSeedsPath() (string, error) {\n\tclient := p.getClient()\n\tif client == nil || client.DeviceID == \"\" {\n\t\treturn \"\", fmt.Errorf(\"matrix: device ID not available\")\n\t}\n\thomeDir, err := os.UserHomeDir()\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"get home dir: %w\", err)\n\t}\n\treturn filepath.Join(homeDir, \".cc-connect\", fmt.Sprintf(\"matrix-cross-signing-%s.json\", client.DeviceID)), nil\n}\n\n// setupCrossSigning bootstraps cross-signing for the bot's own device.\n// Without cross-signing, Element shows \"encrypted by a device not verified\n// by its owner\" on messages from the bot.\nfunc (p *Platform) setupCrossSigning(ctx context.Context, ch *cryptohelper.CryptoHelper) {\n\tmach := ch.Machine()\n\n\t// If private keys are already loaded in memory, just sign our device.\n\tif mach.CrossSigningKeys != nil {\n\t\tp.crossSignOwnDevice(ctx, mach)\n\t\treturn","sourceCodeStart":265,"sourceCodeEnd":301,"githubUrl":"https://github.com/chenhg5/cc-connect/blob/4000b2338aa6e850c99df54f8b0ed6ed7460b401/platform/matrix/verification.go#L265-L301","documentation":"crossSigningSeedsPath returns \"matrix: device ID not available\" when the Matrix client is nil or client.DeviceID is empty. The path for persisting cross-signing seeds is derived from the device ID, so without a device the seeds cannot be stored. Called by setupCrossSigning during E2EE bootstrap.","triggerScenarios":"setupCrossSigning calls crossSigningSeedsPath before the client completed login (DeviceID empty — e.g., token-only login where the server never echoed a device_id) or after the client was cleared.","commonSituations":"Configuring the bot with only an access token where the device ID is not resolved; login response missing device_id due to a homeserver quirk; E2EE setup racing a failed connection.","solutions":["Ensure the client completed a full login so DeviceID is populated before cross-signing setup","If using an access token, also supply the device ID in config or perform a whoami/login call to resolve it","Check earlier logs for login failures explaining the nil client","Skip cross-signing setup gracefully when no device exists yet, and retry after first successful sync"],"exampleFix":"// before\npath, err := p.crossSigningSeedsPath()\n\n// after\nif p.getClient() == nil || p.getClient().DeviceID == \"\" {\n    return fmt.Errorf(\"cross-signing skipped: device ID not yet available\")\n}\npath, err := p.crossSigningSeedsPath()","handlingStrategy":"type-guard","validationCode":"c := p.getClient()\nif c == nil || c.DeviceID == \"\" {\n    // defer cross-signing until device ID is known\n}","typeGuard":"func deviceKnown(c *mautrix.Client) bool { return c != nil && c.DeviceID != \"\" }","tryCatchPattern":"path, err := p.crossSigningSeedsPath()\nif err != nil {\n    slog.Warn(\"cross-signing setup deferred\", \"err\", err)\n    return\n}","preventionTips":["Complete full login (device_id echoed) before cross-signing bootstrap","Supply or resolve the device ID when configuring token-only auth","Retry setup after the first successful sync"],"tags":["matrix","e2ee","cross-signing","device-id"],"backgroundTag":"missing-required-argument","analyzedSha":"4000b2338aa6e850c99df54f8b0ed6ed7460b401","analyzedAt":"2026-09-06T11:45:09.575Z","contentChangedAt":"2026-09-06T11:45:09.575Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}