Skip to content

fix: recover from panic in IsMinikubeKubernetes when kubeconfig extensions are plain strings#3217

Open
benmosher wants to merge 3 commits intodevspace-sh:mainfrom
benmosher:fix/minikube-extension-panic
Open

fix: recover from panic in IsMinikubeKubernetes when kubeconfig extensions are plain strings#3217
benmosher wants to merge 3 commits intodevspace-sh:mainfrom
benmosher:fix/minikube-extension-panic

Conversation

@benmosher
Copy link
Copy Markdown

@benmosher benmosher commented Apr 16, 2026

Problem

When using a Teleport-managed kubeconfig, devspace build (and any pipeline that calls build_images) panics and crashes:

panic: reflect.Set: value of type string is not assignable to type map[string]interface {}

goroutine 123 [running]:
k8s.io/apimachinery/pkg/runtime.toUnstructured(...)
    vendor/k8s.io/apimachinery/pkg/runtime/converter.go:660
k8s.io/apimachinery/pkg/runtime.(*unstructuredConverter).ToUnstructured(...)
    vendor/k8s.io/apimachinery/pkg/runtime/converter.go:586
github.com/loft-sh/devspace/pkg/devspace/kubectl.IsMinikubeKubernetes(...)
    pkg/devspace/kubectl/util.go:258
github.com/loft-sh/devspace/pkg/devspace/kubectl.IsLocalKubernetes(...)
    pkg/devspace/kubectl/util.go:217
github.com/loft-sh/devspace/pkg/devspace/build/builder/buildkit.(*Builder).BuildImage(...)
    pkg/devspace/build/builder/buildkit/buildkit.go:111

Root cause

Teleport writes kubeconfig cluster extensions as plain YAML strings, e.g.:

clusters:
  - cluster:
      extensions:
        - name: teleport.kube.name
          extension: some-cluster-name   # <-- bare string, not an object

The Kubernetes spec says extension values should be structured objects. runtime.DefaultUnstructuredConverter.ToUnstructured() uses reflection and assumes the extension value is a struct/map — it panics (rather than returning an error) when it encounters a plain string.

Fix

Extract the per-extension check into a small helper isMinikubeExtension that wraps the ToUnstructured call with recover(). A malformed/unparseable extension is treated as non-minikube and the build proceeds normally. No behaviour change on the happy path.

Reproduction

  1. Update a cluster's extension to be string-valued
  2. Attempt e.g. devspace build
  3. Observe the panic

Confirmed on devspace v6.3.2 and v6.3.20.

Resolves #3218.

…sions are plain strings

Some tools (e.g. Teleport) write kubeconfig cluster extensions as raw
YAML strings rather than structured objects. When devspace calls
runtime.DefaultUnstructuredConverter.ToUnstructured() on such an
extension, the k8s apimachinery reflection layer panics instead of
returning an error:

  panic: reflect.Set: value of type string is not assignable to
         type map[string]interface {}

Extract the per-extension check into a helper (isMinikubeExtension)
that uses recover() to catch the panic and treat unparseable extensions
as non-minikube, allowing the build to proceed normally.
@netlify
Copy link
Copy Markdown

netlify bot commented Apr 16, 2026

Deploy Preview for devspace-docs canceled.

Built without sensitive environment variables

Name Link
🔨 Latest commit 0ce6070
🔍 Latest deploy log https://app.netlify.com/projects/devspace-docs/deploys/69e14679be96fe0008ca18c0

…anic

Covers the cases for IsMinikubeKubernetes:
- nil client / nil ClientConfig
- context name match ("minikube")
- structured extension with minikube provider
- structured extension with a different provider
- string-valued extension (e.g. written by Teleport) — must not panic
@benmosher
Copy link
Copy Markdown
Author

benmosher commented Apr 16, 2026

FWIW -- I am not a Go guy, so this is 100% Claude Code 😅 but this is a real problem I'm experiencing locally.

and I rebuilt the binary against this patch, and I can build again 👍 so the fix does empirically work.

Without noinline, newer Go versions inline isMinikubeExtension into its
caller, which means the deferred recover() loses its own stack frame and
cannot catch the panic from ToUnstructured.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Panic in IsMinikubeKubernetes when kubeconfig extensions contain plain string values

1 participant