What happened:
The plugin panics with panic triggered: interface conversion: interface {} is float64, not string when datasources are configured with numeric dialTimeout or timeout values via YAML provisioning or HTTP API.
panic triggered: interface conversion: interface {} is float64, not string
Stack trace:
github.com/grafana/clickhouse-datasource/pkg/plugin.LoadSettings({_, _}, ...)
/pkg/plugin/settings.go:154 +0x1f98
What you expected to happen:
The datasource should be created successfully and accept numeric timeout values (as JSON/YAML naturally represents numbers as numeric types, not strings).
How to reproduce it (as minimally and precisely as possible):
Option 1: YAML Provisioning
- Create a datasource provisioning file with numeric
dialTimeout:
apiVersion: 1
datasources:
- name: ClickHouse Test
type: grafana-clickhouse-datasource
url: http://clickhouse:8123
jsonData:
server: clickhouse
port: 9000
dialTimeout: 10 # Numeric value causes panic
queryTimeout: 60 # This works fine!
- Start Grafana with the provisioning file
- Attempt to query the datasource via UI or API
- Plugin panics
Option 2: HTTP API
- Create datasource via API:
curl -X POST http://localhost:3000/api/datasources \
-H "Content-Type: application/json" \
-u admin:admin \
-d '{
"name": "ClickHouse Test",
"type": "grafana-clickhouse-datasource",
"url": "http://clickhouse:8123",
"jsonData": {"dialTimeout": 10}
}'
- Attempt to query the datasource
- Plugin panics
Screenshots
N/A - This is a backend panic that occurs before UI interaction.
Anything else we need to know?:
Root Cause: When Grafana loads datasource configuration, it converts numeric JSON/YAML values to float64 in the jsonData map. The plugin performs a hard type assertion expecting string at line 154:
if jsonData["dialTimeout"] != nil {
settings.DialTimeout = jsonData["dialTimeout"].(string) // PANIC HERE
}
The Fix Already Exists in This Same File!
Ironically, queryTimeout (lines 158-163) already has the correct type-safe implementation:
if jsonData["queryTimeout"] != nil {
if val, ok := jsonData["queryTimeout"].(string); ok {
settings.QueryTimeout = val
}
if val, ok := jsonData["queryTimeout"].(float64); ok {
settings.QueryTimeout = fmt.Sprintf("%d", int64(val))
}
}
Someone fixed queryTimeout but forgot to apply the same fix to dialTimeout and timeout!
Proposed Fix: Apply the same pattern to dialTimeout and timeout:
if jsonData["dialTimeout"] != nil {
if val, ok := jsonData["dialTimeout"].(string); ok {
settings.DialTimeout = val
}
if val, ok := jsonData["dialTimeout"].(float64); ok {
settings.DialTimeout = fmt.Sprintf("%d", int64(val))
}
}
Impact:
- Breaks all Infrastructure-as-Code deployments (Terraform, Ansible, GitOps)
- Affects anyone using YAML provisioning with numeric timeout values
- No workaround available (users cannot control Grafana's type conversion)
Source Code Reference:
Environment:
- Grafana version: 12.2.0 (likely affects all versions)
- Plugin version: 4.11.1, 4.11.2, and current main branch
- OS Grafana is installed on: Linux (Docker), Darwin
- User OS & Browser: N/A (backend panic)
- Others: Verified in current main branch source code
What happened:
The plugin panics with
panic triggered: interface conversion: interface {} is float64, not stringwhen datasources are configured with numericdialTimeoutortimeoutvalues via YAML provisioning or HTTP API.What you expected to happen:
The datasource should be created successfully and accept numeric timeout values (as JSON/YAML naturally represents numbers as numeric types, not strings).
How to reproduce it (as minimally and precisely as possible):
Option 1: YAML Provisioning
dialTimeout:Option 2: HTTP API
Screenshots
N/A - This is a backend panic that occurs before UI interaction.
Anything else we need to know?:
Root Cause: When Grafana loads datasource configuration, it converts numeric JSON/YAML values to
float64in thejsonDatamap. The plugin performs a hard type assertion expectingstringat line 154:The Fix Already Exists in This Same File!
Ironically,
queryTimeout(lines 158-163) already has the correct type-safe implementation:Someone fixed
queryTimeoutbut forgot to apply the same fix todialTimeoutandtimeout!Proposed Fix: Apply the same pattern to
dialTimeoutandtimeout:Impact:
Source Code Reference:
Environment: