bytebase/bytebase · error

failed to unmarshal query data policy payload

Error message

failed to unmarshal query data policy payload

What it means

convertToV1PBQueryDataPolicy parses the stored JSON payload of a query-data policy into storepb.QueryDataPolicy via a strict protojson unmarshaler. On failure it wraps the error as 'failed to unmarshal query data policy payload'. Like the rollout variant, this signals a persisted payload that no longer matches the proto schema.

Source

Thrown at backend/api/v1/org_policy_service_converter.go:169

	if err := common.ProtojsonUnmarshaler.Unmarshal([]byte(payloadStr), p); err != nil {
		return nil, errors.Wrapf(err, "failed to unmarshal rollout policy payload")
	}
	return &v1pb.Policy_RolloutPolicy{
		RolloutPolicy: p,
	}, nil
}

func convertToStorePBRolloutPolicy(policy *v1pb.RolloutPolicy) *storepb.RolloutPolicy {
	return &storepb.RolloutPolicy{
		Automatic: policy.Automatic,
		Roles:     policy.Roles,
	}
}

func convertToV1PBQueryDataPolicy(payloadStr string) (*v1pb.Policy_QueryDataPolicy, error) {
	payload := &storepb.QueryDataPolicy{}
	if err := common.ProtojsonUnmarshaler.Unmarshal([]byte(payloadStr), payload); err != nil {
		return nil, errors.Wrapf(err, "failed to unmarshal query data policy payload")
	}
	return &v1pb.Policy_QueryDataPolicy{
		QueryDataPolicy: &v1pb.QueryDataPolicy{
			DisableExport:        payload.DisableExport,
			MaximumResultRows:    payload.MaximumResultRows,
			DisableCopyData:      payload.DisableCopyData,
			AllowAdminDataSource: payload.AllowAdminDataSource,
		},
	}, nil
}

func convertToQueryDataPolicyPayload(policy *v1pb.QueryDataPolicy) *storepb.QueryDataPolicy {
	return &storepb.QueryDataPolicy{
		DisableExport:        policy.DisableExport,
		MaximumResultRows:    policy.MaximumResultRows,
		DisableCopyData:      policy.DisableCopyData,
		AllowAdminDataSource: policy.AllowAdminDataSource,
	}

View on GitHub (pinned to 1870550677)

Solutions

  1. Fix the stored payload JSON to match storepb.QueryDataPolicy with camelCase protojson keys.
  2. Reset the policy row (delete it) and recreate it via the API so the server writes a valid payload.
  3. Verify you are running the version that owns the current QueryDataPolicy schema; upgrade/downgrade as needed.
  4. Re-save the policy through UpdatePolicy to re-serialize it with protojson.

Example fix

// before (snake_case, plain JSON)
{"disable_export": true, "maximum_result_rows": 100}
// after (protojson)
{"disableExport": true, "maximumResultRows": 100}
Defensive patterns

Strategy: validation

Validate before calling

// Pre-validate that the payload unmarshals as QueryDataPolicy
p := &storepb.QueryDataPolicy{}
if err := common.ProtojsonUnmarshaler.Unmarshal([]byte(payloadStr), p); err != nil {
    return fmt.Errorf("query data policy payload invalid: %w", err)
}

Try / catch

policy, err := svc.GetPolicy(ctx, req)
if err != nil {
    if strings.Contains(err.Error(), "failed to unmarshal query data policy payload") {
        // reset the row and recreate the policy via UpdatePolicy
    }
    return err
}

Prevention

When it happens

Trigger: GetPolicy/ListPolicies on a QUERY_DATA policy whose payload JSON is malformed, has unknown/wrong-typed fields, or uses keys not accepted by protojson (e.g. snake_case like disable_export instead of disableExport).

Common situations: Hand-edited database rows, payloads produced by external tooling with encoding/json, schema drift after version upgrades that changed QueryDataPolicy fields (e.g. addition of disableCopyData), or truncated JSON in the payload column.

Understand the failure class

Background: "cannot parse invalid wire-format data", "cannot unmarshal", "failed unmarshalling": protobuf unmarshal errors explained — this error's family across 10 libraries.

Related errors


AI-assisted analysis of bytebase/bytebase@1870550677 (2026-09-06). Data as JSON: /api/errors/356804546529e369. Report an issue: GitHub.