{"record":{"id":"7e2de13f7e943ad8","repo":"grafana/k6","slug":"unsupported-extension-type-t","errorCode":null,"errorMessage":"unsupported extension type: %T","messagePattern":"unsupported extension type: %T","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"ext/ext.go","lineNumber":68,"sourceCode":"\tName, Path, Version string\n\tType                ExtensionType\n\tModule              any\n}\n\nfunc (e Extension) String() string {\n\treturn fmt.Sprintf(\"%s %s, %s [%s]\", e.Path, e.Version, e.Name, e.Type)\n}\n\n// Register a new extension with the given name and type. This function will\n// panic if an unsupported extension type is provided, or if an extension of the\n// same type and name is already registered.\nfunc Register(name string, typ ExtensionType, mod any) {\n\tmx.Lock()\n\tdefer mx.Unlock()\n\n\texts, ok := extensions[typ]\n\tif !ok {\n\t\tpanic(fmt.Sprintf(\"unsupported extension type: %T\", typ))\n\t}\n\n\tif _, ok := exts[name]; ok {\n\t\tpanic(fmt.Sprintf(\"extension already registered: %s\", name))\n\t}\n\n\tpath, version := extractModuleInfo(mod)\n\n\texts[name] = &Extension{\n\t\tName:    name,\n\t\tType:    typ,\n\t\tModule:  mod,\n\t\tPath:    path,\n\t\tVersion: version,\n\t}\n}\n\n// Get returns all extensions of the specified type.","sourceCodeStart":50,"sourceCodeEnd":86,"githubUrl":"https://github.com/grafana/k6/blob/93accf6570dcd306ca5e99cc44c393ee3797761b/ext/ext.go#L50-L86","documentation":"ext.Register is the API xk6 extensions use at init time to plug modules into k6. The extensions map only has buckets for the four declared ExtensionType constants (JSExtension, OutputExtension, SecretSourceExtension, SubcommandExtension); any other value — including the zero value — finds no bucket and Register panics with the offending type, crashing the binary at startup.","triggerScenarios":"An extension's init() calls ext.Register('k6/x/foo', myType, mod) where myType is a cast like ext.ExtensionType(0), ext.ExtensionType(99), or a locally-defined constant outside the enum. Since ExtensionType is an untyped-able uint8, accidental integer literals compile fine and panic at runtime during binary startup.","commonSituations":"Writing a new xk6 extension and passing an untyped constant 0; copy-pasting a Register call and forgetting to change the type; code written against a newer k6 that adds an extension type, compiled into an older k6 where that bucket does not exist; refactor leaving a stale type value.","solutions":["Use only the exported constants: ext.JSExtension, ext.OutputExtension, ext.SecretSourceExtension, ext.SubcommandExtension","If compiling against older k6, guard with a build tag or version check rather than a raw constant","Fail fast in tests: call ext.Get(type) in a unit test so bad values panic in CI, not at user startup","If you genuinely need a new type, add it to the enum in ext/ext.go and rebuild rather than casting"],"exampleFix":"// before\nfunc init() { ext.Register(\"k6/x/myext\", ext.ExtensionType(0), &MyExt{}) } // panics: unsupported extension type\n\n// after\nfunc init() { ext.Register(\"k6/x/myext\", ext.JSExtension, &MyExt{}) }","handlingStrategy":"validation","validationCode":"// Go, in the extension package\nvar validTypes = map[ext.ExtensionType]bool{\n  ext.JSExtension: true, ext.OutputExtension: true,\n  ext.SecretSourceExtension: true, ext.SubcommandExtension: true,\n}\nfunc register(name string, typ ext.ExtensionType, mod any) {\n  if !validTypes[typ] { panic(fmt.Sprintf(\"bad extension type %d for %s\", typ, name)) }\n  ext.Register(name, typ, mod)\n}","typeGuard":"// Go\nfunc isValidExtType(t ext.ExtensionType) bool { return t >= ext.JSExtension && t <= ext.SubcommandExtension }","tryCatchPattern":null,"preventionTips":["Only use the exported ext constants; never cast integers to ExtensionType","Add a unit test that exercises every Register call in the extension so bad values fail in CI","Avoid 0 as a placeholder — the zero value has no bucket and always panics"],"tags":["extensions","xk6","panic","startup","go"],"backgroundTag":null,"analyzedSha":"93accf6570dcd306ca5e99cc44c393ee3797761b","analyzedAt":"2026-08-15T21:23:27.118Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}