apache/beam · error

multiple locations for

Error message

multiple locations for %v:%v

What it means

validate enforces a 1:1 mapping between artifact names and locations; once a location for a name is seen, the name is marked not-fresh, and a second location with the same name triggers this error. Raised during NewRetrievalServer.

Solutions

  1. Keep exactly one Location per artifact Name; drop duplicate location entries.
  2. Deduplicate locations by Name before constructing the ProxyManifest.
  3. Regenerate the manifest via CommitManifest rather than manual assembly.

Example fix

// before
locs := append(locs, &jobpb.Location{Name: "x", Uri: uriA}, &jobpb.Location{Name: "x", Uri: uriB})
// after
locs := append(locs, &jobpb.Location{Name: "x", Uri: uriA}) // one location per artifact name
Defensive patterns

Strategy: validation

Validate before calling

func locationNamesUnique(md *jobpb.ProxyManifest) error {
	seen := map[string]bool{}
	for _, l := range md.GetLocation() {
		if seen[l.Name] {
			return fmt.Errorf("duplicate location for %v", l.Name)
		}
		seen[l.Name] = true
	}
	return nil
}

Try / catch

if err := gcsproxy.NewRetrievalServer(manifestPath); err != nil {
	if strings.Contains(err.Error(), "multiple locations for") {
		// deduplicate location entries and re-commit the manifest
	}
}

Prevention

When it happens

Trigger: Two or more md.GetLocation() entries carry the same Name while the corresponding artifact appears only once in the manifest (the !fresh branch of validate).

Common situations: Same artifact registered at multiple URIs by a staging bug; duplicated location entries after merging manifests; copy-paste of a location block when hand-assembling the manifest.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


AI-assisted analysis of apache/beam@12126d8942 (2026-09-13). Data as JSON: /api/errors/e3313dc6ca04d683. Report an issue: GitHub.

Appendix: source

Thrown at sdks/go/pkg/beam/artifact/gcsproxy/retrieval.go:136

	}
	return nil
}

func validate(md *jobpb.ProxyManifest) error {
	keys := make(map[string]bool)
	for _, a := range md.GetManifest().GetArtifact() {
		if _, seen := keys[a.Name]; seen {
			return errors.Errorf("multiple artifact with name %v", a.Name)
		}
		keys[a.Name] = true
	}
	for _, l := range md.GetLocation() {
		fresh, seen := keys[l.Name]
		if !seen {
			return errors.Errorf("no artifact named %v for location %v", l.Name, l.Uri)
		}
		if !fresh {
			return errors.Errorf("multiple locations for %v:%v", l.Name, l.Uri)
		}
		keys[l.Name] = false
	}

	for key, fresh := range keys {
		if fresh {
			return errors.Errorf("no location for %v", key)
		}
	}
	return nil
}

func parseObject(blob string) (string, string) {
	bucket, object, err := gcsx.ParseObject(blob)
	if err != nil {
		panic(err)
	}
	return bucket, object

View on GitHub (pinned to 12126d8942)