InfluxDB_HealthCheck.TestWriteAndQuery throws System.ArgumentException: An item with the same key has already been added. Key: write_successful whenever the write succeeds but the query step then throws. The exception escapes the check, so the InfluxDB health check reports a misleading "InfluxDB health check failed" (the ArgumentException) instead of the real underlying error — masking genuine InfluxDB problems (see #483).
Evidence (Seq)
Health check InfluxDB with status Unhealthy ... 'InfluxDB health check failed'
System.ArgumentException: An item with the same key has already been added. Key: write_successful
at SpikerSoft.Api.Infrastructure.HealthChecks.InfluxDB_HealthCheck.TestWriteAndQuery(...)
at ...InfluxDB_HealthCheck.CheckHealthAsync(...)
If the write succeeds (line 203 runs) and the query PostAsync throws (timeout / cancellation / connection reset — plausible given the InfluxDB token issues in #483), control enters the catch and calls healthData.Add("write_successful", false) for a key that is already present -> Dictionary.Add throws ArgumentException. The real exception (ex) is lost.
Fix
Use idempotent indexer assignment in the catch (and ideally throughout) instead of .Add:
catch(Exceptionex){healthData["write_successful"]=false;// indexer: overwrite-safehealthData["query_successful"]=false;errors.Add($"Read/write test failed: {ex.Message}");}
This lets the check surface the actual failure (the ex.Message) instead of a spurious ArgumentException.
Impact
Corrupts the InfluxDB health signal (false "health check failed"), contributing to the Unhealthy/Degraded flaps observed while investigating #483.
Hides the real InfluxDB error, hindering diagnosis.
Priority: low severity, high confidence / trivial fix. Related: #483.
Filed proactively by automated health check (Seq error audit).
## Summary
`InfluxDB_HealthCheck.TestWriteAndQuery` throws `System.ArgumentException: An item with the same key has already been added. Key: write_successful` whenever the write succeeds but the **query step then throws**. The exception escapes the check, so the InfluxDB health check reports a misleading `"InfluxDB health check failed"` (the ArgumentException) instead of the real underlying error — masking genuine InfluxDB problems (see #483).
## Evidence (Seq)
```
Health check InfluxDB with status Unhealthy ... 'InfluxDB health check failed'
System.ArgumentException: An item with the same key has already been added. Key: write_successful
at SpikerSoft.Api.Infrastructure.HealthChecks.InfluxDB_HealthCheck.TestWriteAndQuery(...)
at ...InfluxDB_HealthCheck.CheckHealthAsync(...)
```
## Root cause (code)
`SpikerSoft.Api/Infrastructure/HealthChecks/InfluxDB_HealthCheck.cs`:
- Line 203 (try, after a successful write): `healthData.Add("write_successful", writeResponse.IsSuccessStatusCode);`
- Line 225 (try): `healthData.Add("query_successful", queryResponse.IsSuccessStatusCode);`
- Lines 233-234 (catch):
```csharp
healthData.Add("write_successful", false);
healthData.Add("query_successful", false);
```
If the write succeeds (line 203 runs) and the **query `PostAsync` throws** (timeout / cancellation / connection reset — plausible given the InfluxDB token issues in #483), control enters the catch and calls `healthData.Add("write_successful", false)` for a key that is **already present** -> `Dictionary.Add` throws `ArgumentException`. The real exception (`ex`) is lost.
## Fix
Use idempotent indexer assignment in the catch (and ideally throughout) instead of `.Add`:
```csharp
catch (Exception ex)
{
healthData["write_successful"] = false; // indexer: overwrite-safe
healthData["query_successful"] = false;
errors.Add($"Read/write test failed: {ex.Message}");
}
```
This lets the check surface the actual failure (the `ex.Message`) instead of a spurious ArgumentException.
## Impact
- Corrupts the InfluxDB health signal (false "health check failed"), contributing to the Unhealthy/Degraded flaps observed while investigating #483.
- Hides the real InfluxDB error, hindering diagnosis.
Priority: low severity, **high confidence / trivial fix**. Related: #483.
---
_Filed proactively by automated health check (Seq error audit)._
Resolved in spikersoft-backend PR #213 (merged to master). Both instances of the key-collision class fixed: (1) TestWriteAndQuery's catch now uses indexer assignment and preserves a successful write's recorded value, so write-succeeds-query-throws surfaces the REAL InfluxDB error instead of ArgumentException; (2) a latent second instance found during testing — CheckPingEndpoint's GetValues(X-Influxdb-Version) throws when a proxy strips the header, and its catch double-added ping_available — now TryGetValues + indexer, with ready/bucket catches hardened to match. 4 new xUnit tests including the exact #483-shaped failure. After CI rolls the API, the InfluxDB health check will report the genuine underlying failure for #483. Closing.
Resolved in spikersoft-backend PR #213 (merged to master). Both instances of the key-collision class fixed: (1) TestWriteAndQuery's catch now uses indexer assignment and preserves a successful write's recorded value, so write-succeeds-query-throws surfaces the REAL InfluxDB error instead of ArgumentException; (2) a latent second instance found during testing — CheckPingEndpoint's GetValues(X-Influxdb-Version) throws when a proxy strips the header, and its catch double-added ping_available — now TryGetValues + indexer, with ready/bucket catches hardened to match. 4 new xUnit tests including the exact #483-shaped failure. After CI rolls the API, the InfluxDB health check will report the genuine underlying failure for #483. Closing.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Summary
InfluxDB_HealthCheck.TestWriteAndQuerythrowsSystem.ArgumentException: An item with the same key has already been added. Key: write_successfulwhenever the write succeeds but the query step then throws. The exception escapes the check, so the InfluxDB health check reports a misleading"InfluxDB health check failed"(the ArgumentException) instead of the real underlying error — masking genuine InfluxDB problems (see #483).Evidence (Seq)
Root cause (code)
SpikerSoft.Api/Infrastructure/HealthChecks/InfluxDB_HealthCheck.cs:healthData.Add("write_successful", writeResponse.IsSuccessStatusCode);healthData.Add("query_successful", queryResponse.IsSuccessStatusCode);If the write succeeds (line 203 runs) and the query
PostAsyncthrows (timeout / cancellation / connection reset — plausible given the InfluxDB token issues in #483), control enters the catch and callshealthData.Add("write_successful", false)for a key that is already present ->Dictionary.AddthrowsArgumentException. The real exception (ex) is lost.Fix
Use idempotent indexer assignment in the catch (and ideally throughout) instead of
.Add:This lets the check surface the actual failure (the
ex.Message) instead of a spurious ArgumentException.Impact
Priority: low severity, high confidence / trivial fix. Related: #483.
Filed proactively by automated health check (Seq error audit).
Resolved in spikersoft-backend PR #213 (merged to master). Both instances of the key-collision class fixed: (1) TestWriteAndQuery's catch now uses indexer assignment and preserves a successful write's recorded value, so write-succeeds-query-throws surfaces the REAL InfluxDB error instead of ArgumentException; (2) a latent second instance found during testing — CheckPingEndpoint's GetValues(X-Influxdb-Version) throws when a proxy strips the header, and its catch double-added ping_available — now TryGetValues + indexer, with ready/bucket catches hardened to match. 4 new xUnit tests including the exact #483-shaped failure. After CI rolls the API, the InfluxDB health check will report the genuine underlying failure for #483. Closing.