SonarSource/sonarqube · error · BadRequestException
' ' contains the invalid character ' '. Azure DevOps names…
Error message
'%s' contains the invalid character '%s'. Azure DevOps names must not contain any of: \ / : < > | ? *
What it means
AlmSettingsSupport.validateAzureName checks that Azure DevOps name fields (project, repository, etc.) contain none of the characters \ / : < > | ? *, which Azure DevOps forbids. On violation it logs a warning and throws BadRequestException naming the field and the offending character.
Solutions
- Remove the reported invalid character from the field value named in the message
- Use the Azure DevOps project/repository display name, not a path with slashes
- Sanitize user-supplied names in automation before calling the API
- Rename the project/repo in Azure DevOps if its actual name contains forbidden characters
Example fix
// before
almSettings.updateAzure("ado", "TeamProject/SubProject");
// after
almSettings.updateAzure("ado", "TeamProject SubProject"); Defensive patterns
Strategy: validation
Validate before calling
private static final Pattern INVALID = Pattern.compile("[\\\\/:<>|?*]");
void assertValidAzureName(String v) { Matcher m = INVALID.matcher(v); if (m.find()) throw new IllegalArgumentException("contains invalid character " + m.group()); } Type guard
boolean isValidAzureName(String v) { return v != null && !Pattern.compile("[\\\\/:<>|?*]").matcher(v).find(); } Try / catch
try { support.validateAzureName("project", name); } catch (BadRequestException e) { sanitizeNameAndRetry(); } Prevention
- Sanitize Azure names against \\ / : < > | ? * before API calls
- Use display names, never slash-separated paths
- Document the character restriction wherever Azure settings are collected
When it happens
Trigger: Creating/updating an Azure DevOps ALM setting where the field value passed to validateAzureName contains a forbidden character; the matcher finds the first invalid char and it is embedded in the 400 message.
Common situations: Azure project names containing slashes or spaces-separated paths; automation copying full repo paths ('repo/subdir') into the repository field; names with special characters from templating systems.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- Cannot provide an Azure DevOps access token for project
- Invalid Azure URL or Personal Access Token
- a JVM option can't be empty and must start with '-'. The…
- Address contains invalid character: 0x%02x
- allowAllGroups can only be enabled when Auto-provisioning…
AI-assisted analysis of SonarSource/sonarqube@184c821202 (2026-09-09).
Data as JSON: /api/errors/69f1f7722aba9adb.
Report an issue: GitHub.
Appendix: source
Thrown at server/sonar-webserver-webapi/src/main/java/org/sonar/server/almsettings/ws/AlmSettingsSupport.java:145
}
}
public void validateUrl(@Nullable String url) {
if (url == null || HttpUrl.parse(url) == null) {
LOG.warn("Rejected an invalid DevOps Platform URL");
throw BadRequestException.create(format("Invalid URL: '%s'.", url));
}
}
public void validateAzureName(String fieldName, String value) {
Matcher matcher = AZURE_NAME_INVALID_CHARS.matcher(value);
if (matcher.find()) {
String invalidChar = matcher.group();
if (LOG.isWarnEnabled()) {
LOG.warn("Rejected Azure DevOps name for field '{}': contains invalid character '{}'", fieldName, invalidChar);
}
throw BadRequestException.create(format(
"'%s' contains the invalid character '%s'. Azure DevOps names must not contain any of: \\ / : < > | ? *",
fieldName, invalidChar));
}
}
public ProjectDto getProjectAsAdmin(DbSession dbSession, String projectKey) {
return getProject(dbSession, projectKey, ADMIN);
}
public ProjectDto getProject(DbSession dbSession, String projectKey, ProjectPermission projectPermission) {
ProjectDto project = componentFinder.getProjectByKey(dbSession, projectKey);
userSession.checkEntityPermission(projectPermission, project);
return project;
}
public record NewAzureSetting(String key, String url, String personalAccessToken) {
}
public record NewGitlabSetting(String key, String url, String personalAccessToken) {View on GitHub (pinned to 184c821202)