henrygd/beszel · error

unexpected dest type for CheckFingerprint: %T

Error message

unexpected dest type for CheckFingerprint: %T

What it means

In the legacy fallback of unmarshalLegacyResponse, action common.CheckFingerprint requires dest to be *common.FingerprintResponse; any other destination type triggers 'unexpected dest type for CheckFingerprint: %T'. It protects the copy from resp.Fingerprint into the caller's target.

Source

Thrown at internal/hub/transport/transport.go:63

}

// unmarshalLegacyResponse handles legacy responses that use typed fields.
func unmarshalLegacyResponse(resp common.AgentResponse, action common.WebSocketAction, dest any) error {
	switch action {
	case common.GetData:
		d, ok := dest.(*system.CombinedData)
		if !ok {
			return fmt.Errorf("unexpected dest type for GetData: %T", dest)
		}
		if resp.SystemData == nil {
			return errors.New("no system data in response")
		}
		*d = *resp.SystemData
		return nil
	case common.CheckFingerprint:
		d, ok := dest.(*common.FingerprintResponse)
		if !ok {
			return fmt.Errorf("unexpected dest type for CheckFingerprint: %T", dest)
		}
		if resp.Fingerprint == nil {
			return errors.New("no fingerprint in response")
		}
		*d = *resp.Fingerprint
		return nil
	case common.GetContainerLogs:
		d, ok := dest.(*string)
		if !ok {
			return fmt.Errorf("unexpected dest type for GetContainerLogs: %T", dest)
		}
		if resp.String == nil {
			return errors.New("no logs in response")
		}
		*d = *resp.String
		return nil
	case common.GetContainerInfo:
		d, ok := dest.(*string)

View on GitHub (pinned to b38fb7dafa)

Solutions

  1. Pass a *common.FingerprintResponse as dest for common.CheckFingerprint
  2. Ensure agents are upgraded so responses populate the generic Data field, avoiding the legacy branch
  3. Grep call sites for CheckFingerprint and confirm dest types match

Example fix

// before
var dest map[string]any
err := transport.Request(ctx, common.CheckFingerprint, fpReq, &dest)
// after
var dest common.FingerprintResponse
err := transport.Request(ctx, common.CheckFingerprint, fpReq, &dest)
Defensive patterns

Strategy: type-guard

Validate before calling

if action == common.CheckFingerprint {
    if _, ok := dest.(*common.FingerprintResponse); !ok {
        return fmt.Errorf("CheckFingerprint requires *common.FingerprintResponse, got %T", dest)
    }
}

Type guard

func isFingerprintResponse(dest any) bool {
    _, ok := dest.(*common.FingerprintResponse)
    return ok
}

Try / catch

err := t.Request(ctx, common.CheckFingerprint, req, dest)
if err != nil && strings.Contains(err.Error(), "unexpected dest type for CheckFingerprint") {
    return fmt.Errorf("caller bug: wrong dest type for CheckFingerprint: %w", err)
}

Prevention

When it happens

Trigger: Calling Request with action CheckFingerprint and a dest other than *common.FingerprintResponse while the agent response has no generic Data (legacy 0.18.x agent), forcing the typed-field branch.

Common situations: Refactors or generic wrappers passing the wrong dest; fingerprint-check helpers rewritten to use a new struct while still hitting legacy agents.

Related errors


AI-assisted analysis of henrygd/beszel@b38fb7dafa (2026-08-31). Data as JSON: /api/errors/d657a1c02b9f6b57. Report an issue: GitHub.