LykosAI/StabilityMatrix · error · InvalidOperationException
GetUserAccount did not contain an id
Error message
GetUserAccount did not contain an id
What it means
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.
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
Example fix
// before
await accountsService.CivitLoginAsync(userProvidedToken);
// after
var account = await civitTRPCApi.GetUserAccount(userProvidedToken);
if (account.InnerJson?.Id is null)
{
throw new InvalidOperationException("Civitai token was rejected or returned no account id; check the API key");
}
await accountsService.CivitLoginAsync(userProvidedToken); Defensive patterns
Strategy: validation
Validate before calling
var probe = await civitTRPCApi.GetUserAccount(apiToken);
if (probe.InnerJson?.Id is null)
throw new InvalidOperationException("Token rejected or response missing id; verify the Civitai API key"); Type guard
bool HasAccountId(CivitUserAccount a) => a.InnerJson?.Id is not null;
Try / catch
try
{
await accountsService.CivitLoginAsync(apiToken);
}
catch (InvalidOperationException ex) when (ex.Message.Contains("GetUserAccount did not contain an id"))
{
// surface 'invalid Civitai API token' to the user
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- Lykos account must be connected in to manage OAuth…
- API key is required
- Token is required
- CivArchive list page was missing pageProps
- Relative URL is required
AI-assisted analysis of LykosAI/StabilityMatrix@af93d6ef57 (2026-09-12).
Data as JSON: /api/errors/780d5b7d748d0913.
Report an issue: GitHub.
Appendix: source
Thrown at StabilityMatrix.Avalonia/Services/AccountsService.cs:175
throw new InvalidOperationException(
"Lykos account must be connected in to manage OAuth connections"
);
}
await lykosAuthApiV2.ApiV2OauthPatreon();
await RefreshLykosAsync(secrets);
}
public async Task CivitLoginAsync(string apiToken)
{
var secrets = await secretsManager.SafeLoadAsync();
// Get id first using the api token
var userAccount = await civitTRPCApi.GetUserAccount(bearerToken: apiToken);
var id =
userAccount.InnerJson?.Id
?? throw new InvalidOperationException("GetUserAccount did not contain an id");
// Then get the username using the id
var account = await civitTRPCApi.GetUserById(new CivitGetUserByIdRequest { Id = id }, apiToken);
var username = account.Result.Data.Json.Username;
secrets = secrets with { CivitApi = new CivitApiTokens(apiToken, username) };
await secretsManager.SaveAsync(secrets);
await RefreshCivitAsync(secrets);
}
/// <inheritdoc />
public async Task CivitLogoutAsync()
{
var secrets = await secretsManager.SafeLoadAsync();
await secretsManager.SaveAsync(secrets with { CivitApi = null });
View on GitHub (pinned to af93d6ef57)