{"record":{"id":"521be79842b7ad01","repo":"apache/maven","slug":"bad-substitution-operator-in-variable","errorCode":null,"errorMessage":"Bad substitution operator in: ${variable}","messagePattern":"Bad substitution operator in: (.+?)","errorType":"exception","errorClass":"InterpolatorException","httpStatus":null,"severity":"error","filePath":"impl/maven-impl/src/main/java/org/apache/maven/impl/model/DefaultInterpolator.java","lineNumber":345,"sourceCode":"            // Process the operator value through substitution if it contains variables\n            String processedOpValue = doSubstVars(\n                    opValue, variable, cycleMap, configProps, callback, postprocessor, defaultsToEmptyString);\n\n            // Apply the operator\n            if (\":+\".equals(op)) {\n                if (substValue != null && !substValue.isEmpty()) {\n                    substValue = processedOpValue;\n                    // Skip any remaining operators since we've made a decision\n                    break;\n                }\n            } else if (\":-\".equals(op)) {\n                if (substValue == null || substValue.isEmpty()) {\n                    substValue = processedOpValue;\n                    // Skip any remaining operators since we've made a decision\n                    break;\n                }\n            } else {\n                throw new InterpolatorException(\"Bad substitution operator in: ${\" + variable + \"}\");\n            }\n\n            startIdx = nextIdx >= 0 ? nextIdx : variable.length();\n        }\n\n        if (substValue == null) {\n            if (defaultsToEmptyString) {\n                substValue = \"\";\n            } else {\n                substValue = MARKER + \"{\" + variable + \"}\";\n            }\n        }\n\n        return substValue;\n    }\n\n    private static String resolveVariable(\n            String variable,","sourceCodeStart":327,"sourceCodeEnd":363,"githubUrl":"https://github.com/apache/maven/blob/e4093d4e120eac99d6bdce5ba67cace2f3085c97/impl/maven-impl/src/main/java/org/apache/maven/impl/model/DefaultInterpolator.java#L327-L363","documentation":"The Maven interpolator (DefaultInterpolator) supports only two substitution operators inside ${...} expressions: ':-' (use the following value when the variable is unset or empty) and ':+ ' (use the following value when the variable is set). When an expression contains an operator segment that is neither of these — Bash-style expansions such as ':=', ':?', ':#' — the interpolation fails with InterpolatorException(\"Bad substitution operator in: ${...}\").","triggerScenarios":"A pom.xml or settings property using ${releaseUrl:?releaseUrl must be set} or ${skipTests:=false} in any field the model interpolator processes; shell parameter-expansion syntax copied from scripts into Maven properties.","commonSituations":"Porting shell scripts or Dockerfile ARG defaults into Maven properties; developers assuming full Bash parameter expansion works in pom.xml; typos like ${v:-} vs ${v::-} producing an unexpected operator segment.","solutions":["Replace the unsupported operator with ':-': ${releaseUrl:https://default} style defaults","Implement ':?' (fail if unset) semantics with maven-enforcer's requireProperty rule or a validating mojo instead of the expression","Move complex conditional logic into profiles activated by property presence/absence"],"exampleFix":"<!-- before -->\n<url>${releaseUrl:?releaseUrl must be set}</url>\n\n<!-- after -->\n<url>${releaseUrl:-https://repo.example.com/releases}</url>","handlingStrategy":"validation","validationCode":"// lint property expressions: only ':-' and ':+' operators are supported\nstatic final Pattern BAD_OP = Pattern.compile(\"\\\\$\\\\{[^}]*:[-+?=#@%][^}]*}\");\nstatic void checkExpressions(String pomText) {\n    Matcher m = BAD_OP.matcher(pomText);\n    if (m.find()) throw new IllegalArgumentException(\"Unsupported operator in expression: \" + m.group());\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Use only ${var:-default} and ${var:+alternate} forms in pom.xml and settings.xml","Express 'fail if unset' with maven-enforcer requireProperty, not ':?' syntax","Lint property expressions in CI so shell-style operators never reach the interpolator"],"tags":["maven","interpolation","pom","properties","configuration"],"backgroundTag":"unsupported-string-interpolation","analyzedSha":"e4093d4e120eac99d6bdce5ba67cace2f3085c97","analyzedAt":"2026-08-21T22:58:24.034Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}