henrygd/beszel · error

unexpected dest type for GetContainerLogs: %T

Error message

unexpected dest type for GetContainerLogs: %T

What it means

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

Source

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

		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)
		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) {

View on GitHub (pinned to b38fb7dafa)

Solutions

  1. Pass a *string as dest for common.GetContainerLogs
  2. Upgrade the agent so the generic Data path handles richer types
  3. Fix mismatched call sites found via grep for GetContainerLogs

Example fix

// before
var logs []byte
err := transport.Request(ctx, common.GetContainerLogs, logReq, &logs)
// after
var logs string
err := transport.Request(ctx, common.GetContainerLogs, logReq, &logs)
Defensive patterns

Strategy: type-guard

Validate before calling

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

Type guard

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

Try / catch

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

Prevention

When it happens

Trigger: Calling Request with GetContainerLogs but dest is e.g. *bytes.Buffer, *[]byte, or a custom log struct, on a path where the response has empty Data (legacy agent) so the legacy branch runs.

Common situations: Call sites updated to a richer log type after an upgrade but still talking to old agents; generic request helpers passing non-string destinations.

Related errors


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