{"record":{"id":"780d5b7d748d0913","repo":"LykosAI/StabilityMatrix","slug":"getuseraccount-did-not-contain-an-id","errorCode":null,"errorMessage":"GetUserAccount did not contain an id","messagePattern":"GetUserAccount did not contain an id","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"StabilityMatrix.Avalonia/Services/AccountsService.cs","lineNumber":175,"sourceCode":"            throw new InvalidOperationException(\n                \"Lykos account must be connected in to manage OAuth connections\"\n            );\n        }\n\n        await lykosAuthApiV2.ApiV2OauthPatreon();\n\n        await RefreshLykosAsync(secrets);\n    }\n\n    public async Task CivitLoginAsync(string apiToken)\n    {\n        var secrets = await secretsManager.SafeLoadAsync();\n\n        // Get id first using the api token\n        var userAccount = await civitTRPCApi.GetUserAccount(bearerToken: apiToken);\n        var id =\n            userAccount.InnerJson?.Id\n            ?? throw new InvalidOperationException(\"GetUserAccount did not contain an id\");\n\n        // Then get the username using the id\n        var account = await civitTRPCApi.GetUserById(new CivitGetUserByIdRequest { Id = id }, apiToken);\n        var username = account.Result.Data.Json.Username;\n\n        secrets = secrets with { CivitApi = new CivitApiTokens(apiToken, username) };\n\n        await secretsManager.SaveAsync(secrets);\n\n        await RefreshCivitAsync(secrets);\n    }\n\n    /// <inheritdoc />\n    public async Task CivitLogoutAsync()\n    {\n        var secrets = await secretsManager.SafeLoadAsync();\n        await secretsManager.SaveAsync(secrets with { CivitApi = null });\n","sourceCodeStart":157,"sourceCodeEnd":193,"githubUrl":"https://github.com/LykosAI/StabilityMatrix/blob/af93d6ef57c01cd890d7e0ad0a9ea8c9fcda3002/StabilityMatrix.Avalonia/Services/AccountsService.cs#L157-L193","documentation":"During Civitai account linking, AccountsService fetches the user account with the provided API token and requires the response JSON to contain an id, which is used for the follow-up GetUserById lookup. If the Civitai TRPC response lacks an id, the service throws this InvalidOperationException because it cannot persist a valid CivitApi token record.","triggerScenarios":"Calling AccountsService.CivitLoginAsync(apiToken) when the Civitai GetUserAccount response's InnerJson has no Id — typically because the token is invalid/expired, the API shape changed, or a non-authenticated response was returned.","commonSituations":"User pastes a revoked or mistyped Civitai API key; Civitai API contract change or partial outage returning a body without the expected json.id; rate-limited or error response parsed as a user account.","solutions":["Verify the Civitai API token is valid and active (test it against Civitai) before calling CivitLoginAsync","Inspect the GetUserAccount response shape and update the CivitTRPCApi parsing if Civitai changed its schema","Catch InvalidOperationException and prompt the user to re-enter a valid API token"],"exampleFix":"// before\nawait accountsService.CivitLoginAsync(userProvidedToken);\n// after\nvar account = await civitTRPCApi.GetUserAccount(userProvidedToken);\nif (account.InnerJson?.Id is null)\n{\n    throw new InvalidOperationException(\"Civitai token was rejected or returned no account id; check the API key\");\n}\nawait accountsService.CivitLoginAsync(userProvidedToken);","handlingStrategy":"validation","validationCode":"var probe = await civitTRPCApi.GetUserAccount(apiToken);\nif (probe.InnerJson?.Id is null)\n    throw new InvalidOperationException(\"Token rejected or response missing id; verify the Civitai API key\");","typeGuard":"bool HasAccountId(CivitUserAccount a) => a.InnerJson?.Id is not null;","tryCatchPattern":"try\n{\n    await accountsService.CivitLoginAsync(apiToken);\n}\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"GetUserAccount did not contain an id\"))\n{\n    // surface 'invalid Civitai API token' to the user\n}","preventionTips":["Validate Civitai tokens with a lightweight API call before login","Keep the CivitTRPCApi response parsing in sync with Civitai schema changes","Handle Civitai error/rate-limit responses distinctly from successful accounts"],"tags":["civitai","api","authentication"],"backgroundTag":"unexpected-response-shape","analyzedSha":"af93d6ef57c01cd890d7e0ad0a9ea8c9fcda3002","analyzedAt":"2026-09-12T19:02:43.389Z","contentChangedAt":"2026-09-12T19:02:43.389Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}