{"record":{"id":"f98e76c2a298d8bb","repo":"henrygd/beszel","slug":"unexpected-dest-type-for-getdata-t","errorCode":null,"errorMessage":"unexpected dest type for GetData: %T","messagePattern":"unexpected dest type for GetData: %T","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/hub/transport/transport.go","lineNumber":53,"sourceCode":"\t}\n\t// Try generic Data field first (0.19+)\n\tif len(resp.Data) > 0 {\n\t\tif err := cbor.Unmarshal(resp.Data, dest); err != nil {\n\t\t\treturn fmt.Errorf(\"failed to unmarshal generic response data: %w\", err)\n\t\t}\n\t\treturn nil\n\t}\n\t// Fall back to legacy typed fields for older agents/hubs.\n\treturn unmarshalLegacyResponse(resp, action, dest)\n}\n\n// unmarshalLegacyResponse handles legacy responses that use typed fields.\nfunc unmarshalLegacyResponse(resp common.AgentResponse, action common.WebSocketAction, dest any) error {\n\tswitch action {\n\tcase common.GetData:\n\t\td, ok := dest.(*system.CombinedData)\n\t\tif !ok {\n\t\t\treturn fmt.Errorf(\"unexpected dest type for GetData: %T\", dest)\n\t\t}\n\t\tif resp.SystemData == nil {\n\t\t\treturn errors.New(\"no system data in response\")\n\t\t}\n\t\t*d = *resp.SystemData\n\t\treturn nil\n\tcase common.CheckFingerprint:\n\t\td, ok := dest.(*common.FingerprintResponse)\n\t\tif !ok {\n\t\t\treturn fmt.Errorf(\"unexpected dest type for CheckFingerprint: %T\", dest)\n\t\t}\n\t\tif resp.Fingerprint == nil {\n\t\t\treturn errors.New(\"no fingerprint in response\")\n\t\t}\n\t\t*d = *resp.Fingerprint\n\t\treturn nil\n\tcase common.GetContainerLogs:\n\t\td, ok := dest.(*string)","sourceCodeStart":35,"sourceCodeEnd":71,"githubUrl":"https://github.com/henrygd/beszel/blob/b38fb7dafa60812cc22e6a84ce313e94f1ce0a32/internal/hub/transport/transport.go#L35-L71","documentation":"For legacy (0.18.x) responses without a generic Data field, unmarshalLegacyResponse type-asserts dest to *system.CombinedData when action is common.GetData; a mismatched pointer yields 'unexpected dest type for GetData: %T'. It is a programming-error guard ensuring the typed legacy field is only copied into the correct destination.","triggerScenarios":"Calling Request with action GetData but dest not a *system.CombinedData, on a code path where the agent returned an empty Data field (legacy agent), forcing the legacy branch.","commonSituations":"Refactors changing the dest type without updating all call sites; generic helper functions passing *any or a wrapper struct; mixing new/old hub code with legacy agents.","solutions":["Pass a *system.CombinedData as dest for common.GetData","Check the agent version — with a 0.19+ agent the generic Data path is used and the dest type must match its schema instead","Audit call sites after refactors to keep action/dest pairs consistent"],"exampleFix":"// before\nvar dest any\nerr := transport.Request(ctx, common.GetData, nil, &dest)\n// after\nvar dest system.CombinedData\nerr := transport.Request(ctx, common.GetData, nil, &dest)","handlingStrategy":"type-guard","validationCode":"if action == common.GetData {\n    if _, ok := dest.(*system.CombinedData); !ok {\n        return fmt.Errorf(\"GetData requires *system.CombinedData, got %T\", dest)\n    }\n}","typeGuard":"func isCombinedData(dest any) bool {\n    _, ok := dest.(*system.CombinedData)\n    return ok\n}","tryCatchPattern":"err := t.Request(ctx, common.GetData, nil, dest)\nif err != nil && strings.Contains(err.Error(), \"unexpected dest type for GetData\") {\n    return fmt.Errorf(\"caller bug: wrong dest type for GetData: %w\", err)\n}","preventionTips":["Always pass *system.CombinedData for GetData","Pair each action with a compile-time-checked typed helper","Grep call sites after refactors for action/dest mismatches","Prefer 0.19+ agents so the generic Data path is used"],"tags":["type-mismatch","legacy-compat","programming-error"],"backgroundTag":"unexpected-response-type","analyzedSha":"b38fb7dafa60812cc22e6a84ce313e94f1ce0a32","analyzedAt":"2026-08-31T15:10:10.149Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}