{"record":{"id":"8a600f54808a1ccb","repo":"TechnitiumSoftware/DnsServer","slug":"already-logged-in-please-create-a-new-object-to-u","errorCode":null,"errorMessage":"Already logged in. Please create a new object to use a different API token.","messagePattern":"Already logged in\\. Please create a new object to use a different API token\\.","errorType":"exception","errorClass":"HttpApiClientException","httpStatus":null,"severity":"error","filePath":"DnsServerCore.HttpApi/HttpApiClient.cs","lineNumber":226,"sourceCode":"        {\n            if (!_loggedIn)\n                throw new HttpApiClientException(\"No active session exist to logout.\");\n\n            Stream stream = await _httpClient.GetStreamAsync($\"api/user/logout\", cancellationToken);\n\n            using JsonDocument jsonDoc = await JsonDocument.ParseAsync(stream, cancellationToken: cancellationToken);\n            JsonElement rootElement = jsonDoc.RootElement;\n\n            CheckResponseStatus(rootElement);\n\n            _httpClient.DefaultRequestHeaders.Remove(\"Authorization\");\n            _loggedIn = false;\n        }\n\n        public void UseApiToken(string token)\n        {\n            if (_loggedIn)\n                throw new HttpApiClientException(\"Already logged in. Please create a new object to use a different API token.\");\n\n            _httpClient.DefaultRequestHeaders.Add(\"Authorization\", \"Bearer \" + token);\n            _loggedIn = true;\n        }\n\n        public async Task<DashboardStats> GetDashboardStatsAsync(string actingUsername, DashboardStatsType type = DashboardStatsType.LastHour, bool utcFormat = false, string acceptLanguage = \"en-US,en;q=0.5\", bool dontTrimQueryTypeData = false, DateTime startDate = default, DateTime endDate = default, CancellationToken cancellationToken = default)\n        {\n            if (!_loggedIn)\n                throw new HttpApiClientException(\"No active session exists. Please login and try again.\");\n\n            string path = $\"api/dashboard/stats/get?actingUser={Uri.EscapeDataString(actingUsername)}&type={type}&utc={utcFormat}&dontTrimQueryTypeData={dontTrimQueryTypeData}\";\n\n            if (type == DashboardStatsType.Custom)\n                path += $\"&start={startDate:O}&end={endDate:O}\";\n\n            HttpRequestMessage httpRequest = new HttpRequestMessage(HttpMethod.Get, new Uri(_serverUrl, path));\n            httpRequest.Headers.Add(\"Accept-Language\", acceptLanguage);\n","sourceCodeStart":208,"sourceCodeEnd":244,"githubUrl":"https://github.com/TechnitiumSoftware/DnsServer/blob/d0484b6c1e7439cdc53d67d81e9c876cda2ad756/DnsServerCore.HttpApi/HttpApiClient.cs#L208-L244","documentation":"UseApiToken sets up token-based auth and refuses to run if the client already holds a session (_loggedIn == true), because swapping the Authorization header mid-session would corrupt state. The message explicitly directs the caller to instantiate a new HttpApiClient for a different token. Fires before any HTTP traffic.","triggerScenarios":"Calling UseApiToken after LoginAsync or after a prior UseApiToken on the same instance without resetting it.","commonSituations":"Reusing one HttpApiClient for multiple tokens/accounts; calling UseApiToken inside a loop that processes several tokens.","solutions":["Construct a new HttpApiClient instance for each distinct API token.","Call LogoutAsync first if you must reuse the instance (then UseApiToken).","Prefer a factory method that hands out fresh authenticated clients per token."],"exampleFix":"// before\nclient.UseApiToken(tokenA);\nclient.UseApiToken(tokenB); // throws\n\n// after\nvar clientB = new HttpApiClient(serverUrl);\nclientB.UseApiToken(tokenB);","handlingStrategy":"validation","validationCode":"if (client.IsLoggedIn)\n    throw new InvalidOperationException(\n        \"Client already authenticated. Create a new HttpApiClient for a different token.\");\n\nclient.UseApiToken(token);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Instantiate one HttpApiClient per token.","Use a factory to vend fresh authenticated clients.","Call LogoutAsync before reusing an instance with a new token."],"tags":["http-api","client","session","auth","state"],"backgroundTag":null,"analyzedSha":"d0484b6c1e7439cdc53d67d81e9c876cda2ad756","analyzedAt":"2026-08-13T22:57:35.508Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}