{"record":{"id":"7a585793317d78ef","repo":"istio/istio","slug":"plugin-type-v-not-a-string","errorCode":null,"errorMessage":"plugin type %v not a string","messagePattern":"plugin type (.+?) not a string","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cni/pkg/install/install.go","lineNumber":365,"sourceCode":"\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tplugins, err := util.GetPlugins(cniConfigMap)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"%s: %w\", cniConfigFilepath, err)\n\t\t}\n\n\t\t// Create a map to index plugins by their \"type\" field\n\t\tpluginMap := make(map[string]map[string]any)\n\t\tfor _, rawPlugin := range plugins {\n\t\t\tplugin, err := util.GetPlugin(rawPlugin)\n\t\t\tif err != nil {\n\t\t\t\treturn fmt.Errorf(\"%s: %w\", cniConfigFilepath, err)\n\t\t\t}\n\t\t\tif pluginType, ok := plugin[\"type\"].(string); ok {\n\t\t\t\tpluginMap[pluginType] = plugin\n\t\t\t} else {\n\t\t\t\treturn fmt.Errorf(\"plugin type %v not a string\", plugin[\"type\"])\n\t\t\t}\n\t\t}\n\n\t\t// Verify that the Istio CNI config exists in the CNI config plugin map\n\t\tif _, exists := pluginMap[\"istio-cni\"]; !exists {\n\t\t\treturn fmt.Errorf(\"istio-cni plugin not found in Istio CNI config at %s\", cniConfigFilepath)\n\t\t}\n\n\t\tif useIstioOwnedCNIConfig(cfg) {\n\t\t\t// Verifies the Istio CNI config contains all non istio-cni plugins from the primary CNI config\n\t\t\t// and checks that the plugins are equivalent\n\t\t\tprimaryCNIConfigFilepath, err := getCNIConfigFilepath(ctx, cfg.CNIConfName, cfg.MountedCNINetDir, cfg.ChainedCNIPlugin)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tprimaryCniConfigMap, err := util.ReadCNIConfigMap(primaryCNIConfigFilepath)\n\t\t\tif err != nil {\n\t\t\t\treturn err","sourceCodeStart":347,"sourceCodeEnd":383,"githubUrl":"https://github.com/istio/istio/blob/8dc789c5cf17517c64e3c36cb3288230f149dfae/cni/pkg/install/install.go#L347-L383","documentation":"While indexing each plugin in the Istio CNI conflist by its 'type' field, istio-cni found a plugin whose 'type' is not a JSON string (null, number, boolean, or missing). The '%v' prints the offending value. This is a strict schema check: every CNI plugin entry must have a string 'type'.","triggerScenarios":"A plugin entry in the 'plugins' array of the Istio-owned conflist lacks 'type' or has a non-string value, hit during the per-plugin loop in checkCNIConfig after util.GetPlugin succeeds.","commonSituations":"Hand-edited or templated conflist with a typo (e.g. type: 032 or a commented-out field parsed wrong); a CNI chaining tool injecting a malformed plugin stanza; YAML-to-JSON conversion mistakes when users author the file from a ConfigMap.","solutions":["Open the file named in the preceding context and find the plugin entry whose 'type' is wrong: jq '.plugins[] | select((.type|type) != \"string\")' <file>.","Set a proper string type (e.g. \"istio-cni\", \"portmap\", \"calico\") or remove the invalid entry.","Restart istio-cni-node to re-verify, or delete the file to let it be regenerated."],"exampleFix":"// before:\n{ \"name\": \"bad\", \"type\": null }\n// after:\n{ \"name\": \"portmap\", \"type\": \"portmap\", \"capabilities\": {\"portMappings\": true} }","handlingStrategy":"type-guard","validationCode":"jq -e '.plugins | all(.[]; (.type | type) == \"string\")' /host/etc/cni/net.d/istio-cni-conflist","typeGuard":"func pluginTypeIsString(p map[string]any) (string, bool) {\n    t, ok := p[\"type\"].(string)\n    return t, ok && t != \"\"\n}","tryCatchPattern":null,"preventionTips":["Always include a string 'type' in every plugin stanza when authoring conflists.","Lint generated CNI JSON in CI with a schema check.","Regenerate configs from the source CNI rather than patching them by hand."],"tags":["istio","cni","install","config","schema"],"backgroundTag":null,"analyzedSha":"8dc789c5cf17517c64e3c36cb3288230f149dfae","analyzedAt":"2026-08-15T15:16:55.434Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}