{"record":{"id":"6b138044f8bd3f0b","repo":"juicedata/juicefs","slug":"unsupported-type-t","errorCode":null,"errorMessage":"unsupported type: %T","messagePattern":"unsupported type: %T","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"pkg/meta/sql.go","lineNumber":311,"sourceCode":"\nfunc extractCustomConfig[T string | int](value *url.Values, key string, defaultV T) (T, error) {\n\tif value == nil {\n\t\treturn defaultV, nil\n\t}\n\tif v := value.Get(key); v != \"\" {\n\t\tvalue.Del(key)\n\t\tvar result T\n\t\tswitch any(defaultV).(type) {\n\t\tcase int:\n\t\t\tparsedInt, err := strconv.Atoi(v)\n\t\t\tif err != nil {\n\t\t\t\treturn defaultV, fmt.Errorf(\"failed to parse value as int: %v\", err)\n\t\t\t}\n\t\t\tresult = any(parsedInt).(T)\n\t\tcase string:\n\t\t\tresult = any(v).(T)\n\t\tdefault:\n\t\t\treturn defaultV, fmt.Errorf(\"unsupported type: %T\", defaultV)\n\t\t}\n\t\treturn result, nil\n\t} else {\n\t\treturn defaultV, nil\n\t}\n}\n\ntype prefixMapper struct {\n\tmapper names.Mapper\n\tprefix string\n}\n\nfunc (m prefixMapper) Obj2Table(name string) string {\n\tif name == \"sliceRef\" {\n\t\treturn m.prefix + \"chunk_ref\"\n\t}\n\treturn m.prefix + m.mapper.Obj2Table(name)\n}","sourceCodeStart":293,"sourceCodeEnd":329,"githubUrl":"https://github.com/juicedata/juicefs/blob/c9a67b23e8e08ec23ec331aa6f1675e2319e921c/pkg/meta/sql.go#L293-L329","documentation":"extractCustomConfig is generic over `string | int` and dispatches on the dynamic type of the default value. The default branch returns this error if the generic helper is ever instantiated with a default of any other type, indicating an internal programming error in the caller rather than a user-input problem.","triggerScenarios":"A developer adds a call site of extractCustomConfig with a default value whose type is neither string nor int (e.g. `extractCustomConfig(values, \"flag\", false)`); the type switch falls through to default and returns this error at runtime.","commonSituations":"Refactors extending the helper to new settings types without extending the type switch; practically never hit by end users of a released JuiceFS build.","solutions":["Change the call site so the default value is a string or int (the only supported generic types).","If a new type is genuinely needed, extend the switch in extractCustomConfig (e.g. `case bool:` with strconv.ParseBool).","Add a test instantiating the helper only with string|int to catch regressions."],"exampleFix":"// before\nv, err := extractCustomConfig(values, \"flag\", false)\n// after\nv, err := extractCustomConfig(values, \"flag\", 0) // or extend the switch for bool","handlingStrategy":"type-guard","validationCode":"// compile-time guard for supported default types\nvar _ = []interface{}{extractCustomConfig[int], extractCustomConfig[string]}","typeGuard":"func supportedDefault[T any](d T) bool {\n    switch any(d).(type) {\n    case int, string:\n        return true\n    }\n    return false\n}","tryCatchPattern":"if err != nil {\n    if strings.Contains(err.Error(), \"unsupported type\") {\n        // programmer error: fix the generic instantiation, not runtime config\n    }\n}","preventionTips":["Only instantiate extractCustomConfig with string or int defaults.","Add a unit test instantiating the helper with each supported type.","When adding new settings types, extend the type switch in the same PR."],"tags":["go","generics","internal-error","metadata"],"backgroundTag":"unsupported-operation","analyzedSha":"c9a67b23e8e08ec23ec331aa6f1675e2319e921c","analyzedAt":"2026-09-06T17:55:48.476Z","contentChangedAt":"2026-09-06T17:55:48.476Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}