henrygd/beszel · error
unexpected dest type for GetSmartData: %T
Error message
unexpected dest type for GetSmartData: %T
What it means
unmarshalLegacyResponse handles legacy (0.18.0) agent responses with typed fields. For GetSmartData it accepts only *map[string]smart.SmartData or *smart.SmartDataResponse as the destination. This error means the caller passed some other pointer type, so the legacy response cannot be copied into it.
Source
Thrown at internal/hub/transport/transport.go:106
*d = *resp.String
return nil
case common.GetSmartData:
switch d := dest.(type) {
case *map[string]smart.SmartData:
if resp.SmartData == nil {
return errors.New("no SMART data in response")
}
*d = resp.SmartData
return nil
case *smart.SmartDataResponse:
if resp.SmartData == nil {
return errors.New("no SMART data in response")
}
d.Data = resp.SmartData
d.Complete = resp.SmartComplete
return nil
default:
return fmt.Errorf("unexpected dest type for GetSmartData: %T", dest)
}
case common.GetSystemdInfo:
d, ok := dest.(*systemd.ServiceDetails)
if !ok {
return fmt.Errorf("unexpected dest type for GetSystemdInfo: %T", dest)
}
if resp.ServiceInfo == nil {
return errors.New("no systemd info in response")
}
*d = resp.ServiceInfo
return nil
}
return fmt.Errorf("unsupported action: %d", action)
}
View on GitHub (pinned to b38fb7dafa)
Solutions
- Change the dest argument to *map[string]smart.SmartData or *smart.SmartDataResponse for GetSmartData requests
- Upgrade the agent to 0.19+ so responses use the generic CBOR Data field, which unmarshals into any dest type
- Check the caller of UnmarshalResponse to ensure the dest type matches the action constant
Example fix
// before var data smart.SmartData err := t.Request(ctx, common.GetSmartData, nil, &data) // after var data map[string]smart.SmartData err := t.Request(ctx, common.GetSmartData, nil, &data)
Defensive patterns
Strategy: type-guard
Validate before calling
if _, ok := dest.(*map[string]smart.SmartData); !ok {
if _, ok2 := dest.(*smart.SmartDataResponse); !ok2 {
return fmt.Errorf("GetSmartData dest must be *map[string]smart.SmartData or *smart.SmartDataResponse, got %T", dest)
}
} Type guard
func isSmartDataDest(dest any) bool {
switch dest.(type) {
case *map[string]smart.SmartData, *smart.SmartDataResponse:
return true
}
return false
} Try / catch
if err := t.Request(ctx, common.GetSmartData, nil, dest); err != nil {
var terr *transportError
if strings.Contains(err.Error(), "unexpected dest type") { /* fix dest type */ }
return err
} Prevention
- Always pass *map[string]smart.SmartData or *smart.SmartDataResponse for GetSmartData
- Keep hub and agent versions in sync (0.19+ uses the generic CBOR path)
- Add a unit test asserting dest types accepted per action
When it happens
Trigger: Calling Transport.Request (or UnmarshalResponse) with action common.GetSmartData while dest is a pointer to a type other than map[string]smart.SmartData or smart.SmartDataResponse, AND the agent response has an empty Data field (pre-0.19 agent), forcing the legacy path.
Common situations: Mixing hub/agent versions where legacy responses are still in play; refactoring code to use a custom SMART result struct; passing *smart.SmartData instead of *map[string]smart.SmartData.
Related errors
- unexpected dest type for GetSystemdInfo: %T
- unexpected dest type for GetData: %T
- unexpected dest type for CheckFingerprint: %T
- unexpected dest type for GetContainerLogs: %T
- unexpected dest type for GetContainerInfo: %T
AI-assisted analysis of henrygd/beszel@b38fb7dafa (2026-08-31).
Data as JSON: /api/errors/92b65b2eefdc5ea4.
Report an issue: GitHub.