{"id":"88cc3d2ccb8c5777","repo":"junit-team/junit5","slug":"defaultlocale-can-only-be-used-with-language-tag-88cc3d","errorCode":null,"errorMessage":"@DefaultLocale can only be used with language tag if provider is not set","messagePattern":"@DefaultLocale can only be used with language tag if provider is not set","errorType":"exception","errorClass":"ExtensionConfigurationException","httpStatus":null,"severity":"error","filePath":"junit-jupiter-api/src/main/java/org/junit/jupiter/api/util/DefaultLocaleExtension.java","lineNumber":81,"sourceCode":"\t\t\treturn createFromParts(annotation);\n\t\t}\n\t\telse {\n\t\t\treturn getFromProvider(annotation);\n\t\t}\n\t}\n\n\tprivate static Locale createFromLanguageTag(DefaultLocale annotation) {\n\t\tif (!annotation.language().isEmpty() || !annotation.country().isEmpty() || !annotation.variant().isEmpty()\n\t\t\t\t|| annotation.localeProvider() != NullLocaleProvider.class) {\n\t\t\tthrow new ExtensionConfigurationException(\n\t\t\t\t\"@DefaultLocale can only be used with language tag if language, country, variant and provider are not set\");\n\t\t}\n\t\treturn Locale.forLanguageTag(annotation.value());\n\t}\n\n\tprivate static Locale createFromParts(DefaultLocale annotation) {\n\t\tif (annotation.localeProvider() != NullLocaleProvider.class)\n\t\t\tthrow new ExtensionConfigurationException(\n\t\t\t\t\"@DefaultLocale can only be used with language tag if provider is not set\");\n\t\tString language = annotation.language();\n\t\tString country = annotation.country();\n\t\tString variant = annotation.variant();\n\t\tif (!language.isEmpty() && !country.isEmpty() && !variant.isEmpty()) {\n\t\t\treturn JupiterLocaleUtils.createLocale(language, country, variant);\n\t\t}\n\t\telse if (!language.isEmpty() && !country.isEmpty()) {\n\t\t\treturn JupiterLocaleUtils.createLocale(language, country);\n\t\t}\n\t\telse if (!language.isEmpty() && variant.isEmpty()) {\n\t\t\treturn JupiterLocaleUtils.createLocale(language);\n\t\t}\n\t\telse {\n\t\t\tthrow new ExtensionConfigurationException(\n\t\t\t\t\"@DefaultLocale not configured correctly. When not using a language tag, specify either\"\n\t\t\t\t\t\t+ \" language, or language and country, or language and country and variant.\");\n\t\t}","sourceCodeStart":63,"sourceCodeEnd":99,"githubUrl":"https://github.com/junit-team/junit5/blob/956246301e03d757539f7b76dd5a91f298637563/junit-jupiter-api/src/main/java/org/junit/jupiter/api/util/DefaultLocaleExtension.java#L63-L99","documentation":"Thrown as ExtensionConfigurationException by DefaultLocaleExtension.createFromParts when @DefaultLocale is configured with the language attribute (parts-based mode) AND a non-default localeProvider class. Note: the message text mentions 'language tag' but the code path is the parts-based mode (language=...); the message wording is misleading — the real rule is that the provider attribute is mutually exclusive with all parts-based attributes.","triggerScenarios":"Annotating a test with @DefaultLocale(language = \"en\", localeProvider = MyProvider.class). country= and variant= are irrelevant to this branch; only the combination of a set language and a non-NullLocaleProvider triggers it.","commonSituations":"Migrating from parts-based configuration to a provider and forgetting to clear the language= attribute; misunderstanding that localeProvider is a third mutually-exclusive mode.","solutions":["If you want a provider-supplied Locale, remove language= (and country=, variant=) and set only localeProvider=.","If you want parts-based Locale construction, remove the localeProvider= attribute (leave it as the default NullLocaleProvider)."],"exampleFix":"// before\n@DefaultLocale(language = \"en\", localeProvider = MyLocaleProvider.class)\nvoid test() {}\n\n// after — provider-only mode\n@DefaultLocale(localeProvider = MyLocaleProvider.class)\nvoid test() {}","handlingStrategy":"validation","validationCode":"DefaultLocale d = testClass.getAnnotation(DefaultLocale.class);\nboolean partsSet = !d.language().isEmpty() || !d.country().isEmpty() || !d.variant().isEmpty();\nboolean providerSet = d.localeProvider() != NullLocaleProvider.class;\nif (partsSet && providerSet) {\n    throw new IllegalStateException(\"@DefaultLocale parts and provider are mutually exclusive\");\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["The localeProvider attribute is exclusive — never combine it with language/country/variant.","When switching from parts-based to provider-based config, clear all parts attributes.","Note the message text is misleading ('language tag') but the rule is parts-vs-provider exclusivity."],"tags":["default-locale","extension-configuration","annotation-misuse","junit-jupiter"],"analyzedSha":"956246301e03d757539f7b76dd5a91f298637563","analyzedAt":"2026-08-04T19:25:17.049Z","schemaVersion":2}