cilium/cilium · error

%T with name %s already in test scope

Error message

%T with name %s already in test scope

What it means

RegisterPolicy maintains a map of policy objects keyed by name for the current connectivity test scope. This error is thrown when a policy whose name is already present in the map is registered again. Duplicate registration is rejected because it would silently overwrite a previously registered policy and break later lookups by name.

Source

Thrown at cilium-cli/connectivity/check/policy.go:286

	egress, ingress = t.expectFunc(a)
	if egress.Drop {
		t.Debugf("Expecting egress drops for Action %s: %v", a.name, egress)
	}
	if ingress.Drop {
		t.Debugf("Expecting ingress drops for Action %s: %v", a.name, ingress)
	}

	return egress, ingress
}

func RegisterPolicy[T policy](current map[string]T, policies ...T) (map[string]T, error) {
	for _, p := range policies {
		if p.GetName() == "" {
			return current, fmt.Errorf("adding %T with empty name to test: %v", p, p)
		}
		if _, ok := current[p.GetName()]; ok {
			return current, fmt.Errorf("%T with name %s already in test scope", p, p.GetName())
		}

		current[p.GetName()] = p
	}

	return current, nil
}

func sumMap(m map[string]int) int {
	sum := 0
	for _, v := range m {
		sum += v
	}
	return sum
}

// policyApplyDeleteLock guarantees that only one connectivity test instance
// can apply or delete policies in case of connectivity test concurrency > 1

View on GitHub (pinned to ac7b90affa)

Solutions

  1. Use unique names per policy in a test scope (prefix names with the test/step name).
  2. If the policy content changed, mutate the existing registered object rather than registering a new one with the same name.
  3. Check the map before registering: `if _, ok := scope[name]; ok { ... }` to detect collisions at the call site.
  4. When re-running within a fresh scope, ensure the scope map is reset so stale keys do not collide.

Example fix

// before (second registration collides)
scope, _ := check.RegisterPolicy(scope, p1)
scope, _ := check.RegisterPolicy(scope, p2) // p2 has same name as p1
// after
p2.Name = p2.Name + "-v2"
scope, _ := check.RegisterPolicy(scope, p2)
Defensive patterns

Strategy: validation

Validate before calling

func assertUniqueNames[T interface{ GetName() string }](ps ...T) error {
    seen := map[string]bool{}
    for _, p := range ps {
        n := p.GetName()
        if seen[n] { return fmt.Errorf("duplicate policy name %q", n) }
        seen[n] = true
    }
    return nil
}

Try / catch

scope, err := check.RegisterPolicy(scope, policies...)
if err != nil {
    if strings.Contains(err.Error(), "already in test scope") {
        // deduplicate or rename policies before registering
    }
    return err
}

Prevention

When it happens

Trigger: Calling RegisterPolicy twice (or with variadic args) passing two different policy objects that share the same metadata.name within the same test scope, e.g. re-adding an updated version of a policy instead of mutating the existing one.

Common situations: A test step re-registers a policy after modifying it instead of using the create-or-update path; two policies in different files were given the same name; a shared helper is invoked in a loop with a constant policy name.

Related errors


AI-assisted analysis of cilium/cilium@ac7b90affa (2026-08-31). Data as JSON: /api/errors/5a53d0b8d27fe6bc. Report an issue: GitHub.