{"record":{"id":"4008319fb7ace986","repo":"grafana/k6","slug":"unhandled-extension-type-s","errorCode":null,"errorMessage":"unhandled extension type: %s","messagePattern":"unhandled extension type: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/cmd/version.go","lineNumber":205,"sourceCode":"\t\t\t\tVersion: e.Version,\n\t\t\t}\n\n\t\t\tinfoMap[key] = info\n\t\t\tinfoList = append(infoList, info)\n\t\t}\n\n\t\tswitch e.Type {\n\t\tcase ext.OutputExtension:\n\t\t\tinfo.Outputs = append(info.Outputs, e.Name)\n\t\tcase ext.JSExtension:\n\t\t\tinfo.Imports = append(info.Imports, e.Name)\n\t\tcase ext.SecretSourceExtension:\n\t\t\t// currently, no special handling is needed for secret source extensions\n\t\tcase ext.SubcommandExtension:\n\t\t\t// currently, no special handling is needed for subcommand extensions\n\t\tdefault:\n\t\t\t// report unhandled extension type for future proofing\n\t\t\treturn details, fmt.Errorf(\"unhandled extension type: %s\", e.Type)\n\t\t}\n\t}\n\n\tdetails[\"extensions\"] = infoList\n\n\treturn details, nil\n}\n\ntype versionCmd struct {\n\tgs     *state.GlobalState\n\tisJSON bool\n}\n\nfunc (c *versionCmd) run(cmd *cobra.Command, _ []string) error {\n\tif !c.isJSON {\n\t\troot := cmd.Root()\n\t\troot.SetArgs([]string{\"--version\"})\n\t\t_ = root.Execute()","sourceCodeStart":187,"sourceCodeEnd":223,"githubUrl":"https://github.com/grafana/k6/blob/93accf6570dcd306ca5e99cc44c393ee3797761b/internal/cmd/version.go#L187-L223","documentation":"versionDetailsWithExtensions classifies every registered extension by ext.Type into known kinds (OutputExtension, JSExtension, SecretSourceExtension, SubcommandExtension). The default branch is a forward-compatibility guard: if a binary registers an extension with a type this k6 build does not know, it returns \"unhandled extension type: <type>\" instead of silently dropping it from version details.","triggerScenarios":"A custom xk6 build or embedded k6 registering an ext.Type outside the four handled cases (e.g. a newly introduced extension kind compiled against a different k6 core); version skew between the extension registrar and internal/cmd/version.go.","commonSituations":"k6 forks adding a new extension category without updating the version command; pre-release extension types used with an older vendored k6; embedding k6 as a library and registering custom extension kinds.","solutions":["Rebuild/upgrade so the k6 core handles the new extension type — add the case to internal/cmd/version.go upstream","For embedders, register only supported types (Output, JS, SecretSource, Subcommand) against the vendored k6","File an issue upstream if the unknown type comes from an official extension"],"exampleFix":"// before (embedding k6, registers an unknown kind)\next.Register(ext.NewExtension(myUnknownKind, \"myext\", nil))\n// after\next.Register(ext.NewExtension(ext.JSExtension, \"myext\", myModule)) // use a known ext.Type","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"// Exhaustive guard for extension types before building version details\nfunc knownExtensionType(t ext.Type) bool {\n\tswitch t {\n\tcase ext.OutputExtension, ext.JSExtension, ext.SecretSourceExtension, ext.SubcommandExtension:\n\t\treturn true\n\tdefault:\n\t\treturn false\n\t}\n}","tryCatchPattern":null,"preventionTips":["Build k6 core and extensions from the same source tree/version","When adding a new extension kind, extend internal/cmd/version.go in the same change","Register only supported ext.Type values when embedding k6"],"tags":["extensions","version","xk6","forward-compatibility"],"backgroundTag":null,"analyzedSha":"93accf6570dcd306ca5e99cc44c393ee3797761b","analyzedAt":"2026-08-15T21:23:27.118Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}