{"record":{"id":"cfd3c88aac63eff0","repo":"helm/helm","slug":"missing-runtimeconfig-field","errorCode":null,"errorMessage":"missing runtimeConfig field","messagePattern":"missing runtimeConfig field","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/plugin/metadata.go","lineNumber":90,"sourceCode":"\n\tif m.APIVersion == \"\" {\n\t\terrs = append(errs, errors.New(\"empty APIVersion\"))\n\t}\n\n\tif m.Type == \"\" {\n\t\terrs = append(errs, errors.New(\"empty type field\"))\n\t}\n\n\tif m.Runtime == \"\" {\n\t\terrs = append(errs, errors.New(\"empty runtime field\"))\n\t}\n\n\tif m.Config == nil {\n\t\terrs = append(errs, errors.New(\"missing config field\"))\n\t}\n\n\tif m.RuntimeConfig == nil {\n\t\terrs = append(errs, errors.New(\"missing runtimeConfig field\"))\n\t}\n\n\t// Validate the config itself\n\tif m.Config != nil {\n\t\tif err := m.Config.Validate(); err != nil {\n\t\t\terrs = append(errs, fmt.Errorf(\"config validation failed: %w\", err))\n\t\t}\n\t}\n\n\t// Validate the runtime config itself\n\tif m.RuntimeConfig != nil {\n\t\tif err := m.RuntimeConfig.Validate(); err != nil {\n\t\t\terrs = append(errs, fmt.Errorf(\"runtime config validation failed: %w\", err))\n\t\t}\n\t}\n\n\tif len(errs) > 0 {\n\t\treturn errors.Join(errs...)","sourceCodeStart":72,"sourceCodeEnd":108,"githubUrl":"https://github.com/helm/helm/blob/2a29f1770b62844b27197d2507377361d45ad7c0/internal/plugin/metadata.go#L72-L108","documentation":"Metadata.Validate (internal/plugin/metadata.go:90) requires a non-nil runtimeConfig field. runtimeConfig holds the runtime-specific execution settings - for 'subprocess' this is RuntimeConfigSubprocess (platformCommand, platformHooks, protocolCommands), for 'extism/v1' the wasm module config. It is decoded by convertMetadataRuntimeConfig before Validate runs.","triggerScenarios":"A v1 plugin.yaml without a 'runtimeConfig:' section (or explicitly null). Note that decoding happens first: for runtime 'subprocess' a missing runtimeConfig may also surface as a remarshal/unmarshal error; the 'missing runtimeConfig field' message comes from the metadata-level nil check.","commonSituations":"Legacy-format plugins being migrated: their platformCommand/command/hooks must move under runtimeConfig; authors writing the new format who stop at name/type/runtime/config; empty 'runtimeConfig:' line parsed as null.","solutions":["Add a runtimeConfig block appropriate to the runtime, e.g. 'runtimeConfig:\\n  platformCommand:\\n    - command: ./myplugin' for subprocess","When migrating legacy plugins, map the legacy command/platformCommand and hooks into runtimeConfig (fromMetadataLegacy shows the mapping)","Ensure the runtimeConfig contents validate - RuntimeConfigSubprocess.Validate can add a wrapped 'runtime config validation failed' error"],"exampleFix":"# before\napiVersion: v1\nname: myplugin\ntype: cli/v1\nruntime: subprocess\nversion: 1.0.0\nconfig:\n  shortHelp: does a thing\n\n# after\napiVersion: v1\nname: myplugin\ntype: cli/v1\nruntime: subprocess\nversion: 1.0.0\nconfig:\n  shortHelp: does a thing\nruntimeConfig:\n  platformCommand:\n    - command: ./myplugin","handlingStrategy":"validation","validationCode":"func hasRuntimeConfig(pluginYAMLPath string) bool {\n\tb, err := os.ReadFile(pluginYAMLPath)\n\tif err != nil {\n\t\treturn false\n\t}\n\tvar probe struct {\n\t\tRuntimeConfig map[string]any `yaml:\"runtimeConfig\"`\n\t}\n\treturn yaml.Unmarshal(b, &probe) == nil && probe.RuntimeConfig != nil\n}","typeGuard":null,"tryCatchPattern":"if err := md.Validate(); err != nil {\n\tif strings.Contains(err.Error(), \"missing runtimeConfig field\") {\n\t\t// add runtimeConfig (platformCommand/platformHooks for subprocess runtime)\n\t}\n\treturn err\n}","preventionTips":["When migrating legacy plugins, move command/platformCommand/hooks into runtimeConfig","Never leave 'runtimeConfig:' empty at the end of the file - an empty value parses as null","Validate the whole file with a loader-based test before tagging a release"],"tags":["plugin","plugin-yaml","validation","metadata","runtime-config"],"backgroundTag":null,"analyzedSha":"2a29f1770b62844b27197d2507377361d45ad7c0","analyzedAt":"2026-08-15T22:02:47.490Z","schemaVersion":2},"datasetVersion":"2026-08-16T03:17:38.424Z"}