GoogleContainerTools/skaffold · error

getting metadata accessor: %w

Error message

getting metadata accessor: %w

What it means

updateRuntimeObject deep-copies the deployed object and calls meta.Accessor to obtain its ObjectMeta via the meta/v1 Accessor interface. This error means the object does not implement the interfaces needed to expose metadata (GetObjectKind plus a metadata accessor), so labels cannot be attached to it.

Source

Thrown at pkg/skaffold/deploy/label/labels.go:92

	return nil
}

func addLabels(labels map[string]string, accessor metav1.Object) {
	kv := make(map[string]string)

	copyMap(kv, labels)
	copyMap(kv, accessor.GetLabels())

	accessor.SetLabels(kv)
}

func updateRuntimeObject(ctx context.Context, client dynamic.Interface, disco discovery.DiscoveryInterface, labels map[string]string, res deploy.Artifact, kubeContext string) error {
	originalJSON, _ := json.Marshal(res.Obj)
	modifiedObj := res.Obj.DeepCopyObject()
	accessor, err := meta.Accessor(modifiedObj)
	if err != nil {
		return fmt.Errorf("getting metadata accessor: %w", err)
	}
	name := accessor.GetName()

	addLabels(labels, accessor)

	modifiedJSON, _ := json.Marshal(modifiedObj)
	p, _ := patch.CreateTwoWayMergePatch(originalJSON, modifiedJSON, modifiedObj)

	namespaced, gvr, err := util.GroupVersionResource(disco, modifiedObj.GetObjectKind().GroupVersionKind())
	if err != nil {
		return fmt.Errorf("getting group version resource from obj: %w", err)
	}

	if namespaced {
		var namespace string
		if accessor.GetNamespace() != "" {
			namespace = accessor.GetNamespace()
		} else {

View on GitHub (pinned to a1189de023)

Solutions

  1. Check the deployed manifest decodes into a valid Kubernetes object with metadata (name field present)
  2. If using unstructured objects, convert via unstructured.Unstructured which implements the accessor interfaces
  3. Update Skaffold — upstream fixes have addressed accessor issues for newer API types
  4. File a bug with the manifest/GVK that triggers it if the object is a standard built-in type

Example fix

// before
var obj interface{} = someCustomStruct
// after
u := &unstructured.Unstructured{}
u.UnmarshalJSON(manifestBytes) // implements meta.Accessor
Defensive patterns

Strategy: type-guard

Type guard

func hasMetadata(obj runtime.Object) bool {
    if obj == nil { return false }
    _, err := meta.Accessor(obj)
    return err == nil
}

Try / catch

accessor, err := meta.Accessor(modifiedObj)
if err != nil {
    return fmt.Errorf("object %T lacks ObjectMeta, skipping labels: %w", modifiedObj, err)
}

Prevention

When it happens

Trigger: A deploy.Artifact whose Obj is not a proper k8s API runtime.Object with ObjectMeta — e.g. a custom/unregistered type, nil object, or a type from an API group lacking the MetadataAccessor implementation.

Common situations: Deploying CRDs through custom renderers whose manifests decode into unstructured/generic types without metadata; passing objects decoded into the wrong Go type; a bug in a custom deployer feeding results into labeling.

Related errors


AI-assisted analysis of GoogleContainerTools/skaffold@a1189de023 (2026-09-05). Data as JSON: /api/errors/6de7f1b85af0f73c. Report an issue: GitHub.