henrygd/beszel · error

unexpected dest type for GetContainerInfo: %T

Error message

unexpected dest type for GetContainerInfo: %T

What it means

For legacy responses, unmarshalLegacyResponse requires dest to be *string when action is common.GetContainerInfo; otherwise it returns 'unexpected dest type for GetContainerInfo: %T'. The container info string arrives in the typed resp.String field and is copied only into a *string target.

Source

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

		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)
		if !ok {
			return fmt.Errorf("unexpected dest type for GetContainerInfo: %T", dest)
		}
		if resp.String == nil {
			return errors.New("no info in response")
		}
		*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")
			}

View on GitHub (pinned to b38fb7dafa)

Solutions

  1. Pass a *string as dest for common.GetContainerInfo
  2. Upgrade the agent so generic Data responses are used and dest can match the richer schema
  3. Audit GetContainerInfo call sites to keep action/dest pairs consistent

Example fix

// before
var info struct{ ID string `json:"id"` }
err := transport.Request(ctx, common.GetContainerInfo, infoReq, &info)
// after
var info string
err := transport.Request(ctx, common.GetContainerInfo, infoReq, &info)
Defensive patterns

Strategy: type-guard

Validate before calling

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

Type guard

func isStringPtr(dest any) bool {
    _, ok := dest.(*string)
    return ok
}

Try / catch

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

Prevention

When it happens

Trigger: Calling Request with GetContainerInfo and a dest other than *string while the response's generic Data field is empty (legacy 0.18.x agent), forcing the legacy branch.

Common situations: Call sites changed to a struct dest (e.g. docker inspect struct) incompatible with the legacy path; helper functions parameterized with the wrong type.

Related errors


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