Fix bound-CRD sort comparator reading annotation from wrong element

Closed Beginner friendly
#4,444 0 comments 0 reactions 0 assignees View on GitHub

Maintainers usually reply within 1 day

@pujitha24 is already working on this.

Since Oct 9, 2026.

  • #4446 by @pujitha24 — open
  • #4452 by @Sarthak-Shreshtha01 — open

Assessment

Difficulty
1/5
Estimated time
Under an hour
Newbie friendliness
88/100
Issue type
Bug
Clarity
Clearly specified
Activity status
Active
Tech stack
go
Domain
backend

Research direction

The comparator is byClusterAndName.Less in pkg/server/openapiv3/servicecache.go, around line 311, where the bound-CRD annotation is read from the wrong index. Start there and check which element each of the two lookups uses. Run the temporary repro test named in the issue, TestReproBoundSort in pkg/server/openapiv3. Done when a bound CRD sorts before a plain one and that test passes.

Written by the indexing model from the issue text.

Description

Description

I found a copy-paste bug in the OpenAPI v3 cache's CRD ordering: byClusterAndName.Less in pkg/server/openapiv3/servicecache.go:311 reads the bound-CRD annotation from a[i] twice instead of comparing a[i] against a[j]:

_, aBound := a[i].Annotations[BoundAnnotationKey]
_, bBound := a[i].Annotations[BoundAnnotationKey] // should be a[j]

Because bBound always equals aBound, the aBound && !bBound / !aBound && bBound branches never fire and bound CRDs (those carrying apis.kcp.io/bound-crd) are never sorted ahead of regular CRDs. Ordering then falls through to cluster/name comparison, so the resulting orderedCRDs list — and therefore the deterministic API-configuration key built from it in apiConfigurationKey — depends on CRD names rather than the intended bound-first order. In the worst case two logically different orderings can produce different cache keys for the same configuration, or the merge order of bound vs. local specs in addSpecs is not the intended one.

Reproduce
  1. Add a temporary test in pkg/server/openapiv3 with a bound CRD named zzz.example.com (annotation apis.kcp.io/bound-crd: "true") and a plain CRD named aaa.example.com.
  2. Run go test ./pkg/server/openapiv3/ -run TestReproBoundSort -v -count=1.
  3. Observed result: Less(bound,plain)=false, Less(plain,bound)=true, and after sort.Sort the order is [aaa.example.com zzz.example.com] — the bound CRD is not sorted first, so the test fails with BUG: bound CRD not sorted first.
Expected

Less should read the annotation from a[j] on line 311 (_, bBound := a[j].Annotations[BoundAnnotationKey]), so a bound CRD always sorts before a non-bound one and the one-line fix restores the intended deterministic ordering and cache-key stability.

Checklist
  • Searched open issues for openapi/bound/sort (0 hits) and triaged 4 closed items -- no bound-sort comparator report
  • File:line + repro provided

Distinct from bug: something is spamming bound CRD resolution #4216, which is about noisy log spam from bound-CRD lookups at startup; this report is about the Less comparator in the OpenAPI v3 service cache never ordering bound CRDs first.

Dominant language
Go
Stars
2.9k
Forks
471
Avg merge
1d 19h
Merged PRs (30d)
55

Getting set up

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from kcp-dev/kcp

All issues in kcp-dev/kcp

Similar issues

More Go issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.