What happened?
devspace build panics with reflect.Set: value of type string is not assignable to type map[string]interface {} when the kubeconfig contains extensions with plain string values (e.g. from Teleport).
panic: reflect.Set: value of type string is not assignable to type map[string]interface {}
goroutine 222 [running]:
reflect.Value.assignTo(...)
k8s.io/apimachinery/pkg/runtime.toUnstructured(...)
k8s.io/apimachinery@v0.29.0/pkg/runtime/converter.go:660
k8s.io/apimachinery/pkg/runtime.(*unstructuredConverter).ToUnstructured(...)
k8s.io/apimachinery@v0.29.0/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
The kubeconfig is valid — the v1 spec defines Extension as runtime.RawExtension, which accepts any JSON value including plain strings. Teleport generates extensions like:
clusters:
- cluster:
extensions:
- extension: mycompany.teleport.sh
name: kubeconfig.teleport.dev/profile-name
IsMinikubeKubernetes calls runtime.DefaultUnstructuredConverter.ToUnstructured() on these extensions, which panics because it expects a struct/map, not a string.
What did you expect to happen instead?
devspace build should not panic on valid kubeconfig files. The ToUnstructured call should either be guarded with recover(), or replaced with direct type assertion on *runtime.Unknown and json.Unmarshal of its raw bytes.
How can we reproduce the bug?
Use any kubeconfig with plain-string cluster extensions (Teleport generates these by default) and run devspace build.
Local Environment:
- DevSpace Version: 6.3.20
- Operating System: macOS
- ARCH: ARM64
Kubernetes Cluster:
- Cloud Provider: AWS (via Teleport proxy)
- Kubernetes Version: v1.31
Anything else we need to know?
Workaround: strip extensions from the kubeconfig before invoking devspace:
kubectl config view --raw --minify | python3 -c "
import sys, yaml
config = yaml.safe_load(sys.stdin)
for c in config.get('clusters', []): c.get('cluster', {}).pop('extensions', None)
for c in config.get('contexts', []): c.get('context', {}).pop('extensions', None)
yaml.dump(config, sys.stdout, default_flow_style=False)
" > /tmp/stripped-kubeconfig.yaml
KUBECONFIG=/tmp/stripped-kubeconfig.yaml devspace build
What happened?
devspace buildpanics withreflect.Set: value of type string is not assignable to type map[string]interface {}when the kubeconfig contains extensions with plain string values (e.g. from Teleport).The kubeconfig is valid — the v1 spec defines
Extensionasruntime.RawExtension, which accepts any JSON value including plain strings. Teleport generates extensions like:IsMinikubeKubernetescallsruntime.DefaultUnstructuredConverter.ToUnstructured()on these extensions, which panics because it expects a struct/map, not a string.What did you expect to happen instead?
devspace buildshould not panic on valid kubeconfig files. TheToUnstructuredcall should either be guarded withrecover(), or replaced with direct type assertion on*runtime.Unknownandjson.Unmarshalof its raw bytes.How can we reproduce the bug?
Use any kubeconfig with plain-string cluster extensions (Teleport generates these by default) and run
devspace build.Local Environment:
Kubernetes Cluster:
Anything else we need to know?
Workaround: strip extensions from the kubeconfig before invoking devspace: