argoproj/argo-workflows · error

artifact key %q must have a valid UUID segment: %w

Error message

artifact key %q must have a valid UUID segment: %w

What it means

ValidateUploadedArtifactKey validates that a client-supplied artifact key exactly matches the upload-endpoint format uploads/{namespace}/{uuid}/{filename}. The third segment must parse as a UUID (github.com/google/uuid.Parse). This check exists because the key is applied to the artifact location without further verification, so malformed segments could otherwise enable path manipulation or key confusion.

Source

Thrown at server/utils/artifactkey.go:45

	}
	if strings.HasPrefix(key, "/") {
		return fmt.Errorf("artifact key %q must not be an absolute path", key)
	}
	if path.Clean(key) != key {
		return fmt.Errorf("artifact key %q is not in canonical form", key)
	}

	parts := strings.Split(key, "/")
	if len(parts) != 4 {
		return fmt.Errorf("artifact key %q must have exactly 4 segments: uploads/{namespace}/{uuid}/{filename}", key)
	}
	if slices.Contains(parts, "") {
		return fmt.Errorf("artifact key %q must not contain empty segments", key)
	}

	uuidSegment := parts[2]
	if _, err := uuid.Parse(uuidSegment); err != nil {
		return fmt.Errorf("artifact key %q must have a valid UUID segment: %w", key, err)
	}

	filename := parts[3]
	if path.Base(filename) != filename {
		return fmt.Errorf("artifact key %q must have a bare filename segment", key)
	}

	return nil
}

View on GitHub (pinned to 35bff19146)

Solutions

  1. Use the exact key string returned by the artifact upload endpoint rather than constructing it by hand.
  2. Verify the key has exactly 4 segments and that segment index 2 is a valid UUID: run uuid.Parse on it client-side before sending.
  3. If you have only the filename, re-request a fresh upload slot from the server so a correct UUID is generated.

Example fix

// before
key := "uploads/myns/step-1-output/results.tgz"
// after
key := fmt.Sprintf("uploads/%s/%s/%s", namespace, uuid.NewString(), "results.tgz")
Defensive patterns

Strategy: validation

Validate before calling

func looksLikeUploadKey(namespace, key string) bool {
    parts := strings.Split(key, "/")
    return len(parts) == 4 && parts[0] == "uploads" && parts[1] == namespace &&
        func() bool { _, err := uuid.Parse(parts[2]); return err == nil }()
}

Type guard

func isValidUUID(s string) bool { _, err := uuid.Parse(s); return err == nil }

Try / catch

if err := utils.ValidateUploadedArtifactKey(ns, key); err != nil {
    var uerr *uuid.Error
    if errors.As(err, &uerr) {
        return fmt.Errorf("regenerate upload key: UUID segment invalid: %w", err)
    }
    return err
}

Prevention

When it happens

Trigger: Calling ValidateUploadedArtifactKey with a key whose 3rd '/'-separated segment (parts[2]) is not a parseable UUID — e.g. 'uploads/myns/not-a-uuid/file.txt', 'uploads/myns/12345/file.txt', or 'uploads/myns//file.txt' shaped so the uuid slot holds arbitrary text.

Common situations: Hand-constructing artifact keys instead of using the ones the upload endpoint generated; copying a key and truncating/altering the UUID; tools that build keys from workflow/step names instead of the server-generated UUID; version drift where older clients produced keys without the UUID segment.

Related errors


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