stacklok / stacklok/toolhive

Extract mutation from Validate method into separate defaulting logic

Open
#4,628 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

api bug go kubernetes operator vmcp
Dominant language
Go
Stars
2.2k
Forks
300
Avg merge
1d 15h
Merged PRs (30d)
184

Description

Summary

The validateEmbeddingServer method on VirtualMCPServer mutates r.Spec.Config.Optimizer during validation — a defaulting operation hidden inside a validation function. The mutation is never persisted to the API server, is re-applied every reconciliation from a fresh cache copy, and is invisible to users via kubectl get.

Severity: MUST FIX
Area: API Design
Breaking: No

Location

  • cmd/thv-operator/api/v1alpha1/virtualmcpserver_types.go:475-480

Problem

// EmbeddingServerRef is set but optimizer is not configured: auto-populate
// optimizer with default values so the embedding server is actually used.
if hasRef && !hasOptimizer {
    r.Spec.Config.Optimizer = &config.OptimizerConfig{}
}

This mutation inside a Validate() method:

  1. Is never persisted to the API server (the controller doesn't write back to spec)
  2. Is re-applied every reconciliation from a fresh cache copy
  3. Is invisible to users via kubectl get

Impact

  • Violation of separation of concerns (validation should not mutate)
  • Users see a different spec than what the controller uses
  • If webhooks are implemented, this logic would need to be a Defaulter, not a Validator

Recommended Fix

  1. Extract to a separate ApplyDefaults() method or a proper Default() webhook
  2. Call ApplyDefaults() before Validate() in the controller
  3. Document that the defaulting is controller-side only

Contributor guide

Open the contributing guide

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.

Research direction

Start in cmd/thv-operator/api/v1alpha1/virtualmcpserver_types.go:475-480 and inspect validateEmbeddingServer and the controller path that calls validation. Separate the defaulting step from validation, invoke it before Validate, and verify the relevant operator/API tests pass while the existing embedding-server behavior is preserved.

Written by the indexing model from the issue text.

Assessment

Tech stack
go, kubernetes
Domain
backend-api-design, devops
Issue type
Refactor
Difficulty
3/5
Estimated time
1-2 days
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
68/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.