argoproj/argo-workflows · error

plugin %s list objects failed: %w

Error message

plugin %s list objects failed: %w

What it means

Driver.ListObjects calls the plugin's ListObjects RPC to enumerate artifact keys. If the gRPC call itself fails (transport error, deadline, unimplemented, invalid request), the driver wraps it as "plugin %s list objects failed: %w" and returns no objects. The plugin's own logical error string is handled separately (error 514).

Source

Thrown at workflow/artifacts/plugin/plugin.go:348

		Artifact: grpcArtifact,
	})
	if err != nil {
		return fmt.Errorf("plugin %s delete failed: %w", d.pluginName, err)
	}
	if !resp.Success {
		return fmt.Errorf("plugin %s delete failed: %s", d.pluginName, resp.Error)
	}
	return nil
}

// ListObjects implements ArtifactDriver.ListObjects by calling the plugin service
func (d *Driver) ListObjects(ctx context.Context, artifactRef *wfv1.Artifact) ([]string, error) {
	grpcArtifact := convertToGRPC(artifactRef)
	resp, err := d.client.ListObjects(ctx, &artifact.ListObjectsRequest{
		Artifact: grpcArtifact,
	})
	if err != nil {
		return nil, fmt.Errorf("plugin %s list objects failed: %w", d.pluginName, err)
	}
	if resp.Error != "" {
		return nil, fmt.Errorf("plugin %s list objects failed: %s", d.pluginName, resp.Error)
	}
	return resp.Objects, nil
}

// IsDirectory implements ArtifactDriver.IsDirectory by calling the plugin service
func (d *Driver) IsDirectory(ctx context.Context, artifactRef *wfv1.Artifact) (bool, error) {
	grpcArtifact := convertToGRPC(artifactRef)
	resp, err := d.client.IsDirectory(ctx, &artifact.IsDirectoryRequest{
		Artifact: grpcArtifact,
	})
	if err != nil {
		return false, fmt.Errorf("plugin %s is directory check failed: %w", d.pluginName, err)
	}
	if resp.Error != "" {
		return false, fmt.Errorf("plugin %s is directory check failed: %s", d.pluginName, resp.Error)

View on GitHub (pinned to 35bff19146)

Solutions

  1. Unwrap the %w gRPC status: Unavailable → restart/fix the plugin; Unimplemented → upgrade the plugin to one that implements ListObjects.
  2. Validate the artifact reference key/prefix before calling so the request isn't InvalidArgument.
  3. Increase the context timeout or narrow the listed prefix if deadline exceeded on large listings.
  4. Check plugin logs for server-side errors (auth failure to backend, throttling).

Example fix

// validating the ref before listing
// before:
objs, err := driver.ListObjects(ctx, art) // art.Key == ""
// after:
if art.Key == "" {
	return fmt.Errorf("artifact key required for ListObjects")
}
objs, err := driver.ListObjects(ctx, art)
Defensive patterns

Strategy: validation

Validate before calling

// validate request inputs before calling ListObjects
func validateListRef(a *wfv1.Artifact) error {
	if a == nil {
		return errors.New("nil artifact ref")
	}
	if a.GetKey() == "" {
		return errors.New("artifact key/prefix required for ListObjects")
	}
	if ctx.Err() != nil {
		return ctx.Err()
	}
	return nil
}

Type guard

func isUnimplementedList(err error) bool {
	return status.Code(err) == codes.Unimplemented // plugin binary lacks ListObjects
}

Try / catch

objs, err := driver.ListObjects(ctx, art)
if err != nil {
	if isUnimplementedList(err) {
		return nil, fmt.Errorf("plugin %s too old for listing; upgrade plugin image", pluginName)
	}
	if status.Code(err) == codes.DeadlineExceeded {
		ctx2, cancel := context.WithTimeout(context.Background(), 5*time.Minute)
		defer cancel()
		return driver.ListObjects(ctx2, art) // retry with larger budget
	}
	return nil, err
}

Prevention

When it happens

Trigger: Calling Driver.ListObjects(ctx, artifactRef) when the RPC returns a gRPC error: plugin not running (Unavailable), plugin binary lacks ListObjects (Unimplemented), ctx deadline exceeded while listing a huge prefix, or InvalidArgument from a malformed artifact ref (empty/unset key prefix).

Common situations: Archived workflow log/artifact listing against a plugin that was restarted; old plugin image missing ListObjects; very large buckets causing deadline exceeded; artifact ref key left empty by a template bug so the request is invalid.

Related errors


AI-assisted analysis of argoproj/argo-workflows@35bff19146 (2026-09-03). Data as JSON: /api/errors/ba8df6df0c4b19f3. Report an issue: GitHub.