kubesphere/kubesphere · error
failed to build merge specs: %v
Error message
failed to build merge specs: %v
What it means
v2.MergeSpecCache builds a single merged OpenAPI v2 spec from all cached APIService specs using MergeSpecsIgnorePathConflictRenamingDefinitionsAndParameters. This error wraps any failure of that merge (including the GVK extension shape errors 60-63) with a 'failed to build merge specs' prefix.
Source
Thrown at kube/pkg/openapi/v2/services.go:86
func (s *OpenApiV2Services) RemoveApiService(apiServiceName string) {
s.openApiAggregatorService.RemoveApiService(apiServiceName)
delete(s.openApiSpecCache, apiServiceName)
}
func (s *OpenApiV2Services) MergeSpecCache() (*spec.Swagger, error) {
var merged *spec.Swagger
for i := range s.openApiSpecCache {
if cacheValue, ok := s.openApiSpecCache[i]; ok {
cacheSpec := cacheValue.Load()
if merged == nil {
merged = &spec.Swagger{}
*merged = *cacheSpec
merged.Paths = nil
merged.Definitions = nil
merged.Parameters = nil
}
if err := merge.MergeSpecsIgnorePathConflictRenamingDefinitionsAndParameters(merged, cacheSpec); err != nil {
return nil, fmt.Errorf("failed to build merge specs: %v", err)
}
}
}
return merged, nil
}
func (s *OpenApiV2Services) RegisterOpenAPIVersionedService(servePath string, handler openapi.PathHandler) {
handler.Handle(servePath, gziphandler.GzipHandler(http.HandlerFunc(
func(w http.ResponseWriter, r *http.Request) {
result, err := s.MergeSpecCache()
if err != nil {
klog.Errorf("Error in OpenAPI handler: %s", err)
// only return a 503 if we have no older cache data to serve
if result == nil {
w.WriteHeader(http.StatusServiceUnavailable)
return
}View on GitHub (pinned to 04a29b5c60)
Solutions
- Identify the inner (wrapped) error to find the offending cached spec and fix or delete that cache entry
- Clear the spec cache so all specs are re-downloaded and re-merged
- Fix the malformed extension in the offending spec (array of {group,kind,version} objects)
- Validate each cached spec parses and has well-formed extensions before merging
Defensive patterns
Strategy: try-catch
Validate before calling
// pre-validate cached specs before merging
for name, spec := range cache {
if !validGVKExtension(spec) {
invalidateCacheEntry(name)
}
} Type guard
func validGVKExtension(spec map[string]interface{}) bool {
ext, ok := spec["x-kubernetes-group-version-kind"].([]interface{})
if !ok { return false }
for _, x := range ext {
if _, ok := x.(map[string]interface{}); !ok { return false }
}
return true
} Try / catch
merged, err := v2.MergeSpecCache(cache)
if err != nil {
if strings.Contains(err.Error(), "failed to build merge specs") {
// identify and purge the offending cache entry, then rebuild
clearCache()
return v2.MergeSpecCache(reloadCache())
}
return err
} Prevention
- Purge and rebuild the spec cache after unexplained merge failures
- Validate every cached spec's extensions before merging
- Keep spec generators consistent across all aggregated APIs
When it happens
Trigger: During MergeSpecCache iteration over cached specs, merging a subsequent cached spec into the accumulated merged spec fails — typically because a cached spec has a malformed x-kubernetes-group-version-kind extension or otherwise incompatible spec content.
Common situations: One corrupted or hand-written cached spec poisons the whole merge; specs from differently-versioned generators conflict; empty/invalid cached documents left after failed downloads.
Related errors
- failed to build merge specs: %v
- expected slice of GroupVersionKinds, got: %+v
- expected {"group": <group>, "kind": <kind>, "version": <vers
- fetch ApiService %s openapi-v2 error: %s
- update OpenApiSpec failed beaseuse of apiService %s not foun
AI-assisted analysis of kubesphere/kubesphere@04a29b5c60 (2026-09-03).
Data as JSON: /api/errors/5c73f81730d0e4f2.
Report an issue: GitHub.