{"record":{"id":"858bcaeb1db80631","repo":"Tencent/tinker","slug":"invalid-version-fullversion","errorCode":null,"errorMessage":"Invalid version: ${fullVersion}","messagePattern":"Invalid version: (.+?)","errorType":"exception","errorClass":"GradleException","httpStatus":null,"severity":"error","filePath":"gradle/WeChatPublish.gradle","lineNumber":172,"sourceCode":"        checkVersion()\n\n        if (!usedDefaultIsSnapshot) {\n            System.err.println 'isSnapshot should be avoided in build scripts.'\n        }\n\n        if (isSnapshot) {\n            // Bintray does not allow SNAPSHOT publish\n            publishToBintray = false\n        }\n\n        project.ext.fullVersion = fullVersion\n    }\n\n    private void checkVersion() {\n        if (!(fullVersion ==~ /\\d+\\.\\d+(?:\\.\\d+)?(?:\\.\\d+)?(?:\\.\\d+)?(?:-[\\w-]+)?/)) {\n            def message = \"Invalid version: ${fullVersion}\"\n            if (!isSnapshot)\n                throw new GradleException(message)\n            System.err.println(message)\n        }\n    }\n\n    final protected String getPublicationName() {\n        String result = \"\"\n        artifactId.split(\"[-_]\").each { result += it.capitalize() }\n        return uncapitalize(result)\n    }\n\n    protected void mountAdditionalLogic(project) {}\n\n    protected void emitPublicationDSL(Project project) {}\n\n    private void emitSigningConfig(Project project) {\n        project.ext['signing.keyId'] = project.findProperty(\"signingKeyId\")\n        project.ext['signing.password'] = project.findProperty(\"signingPassword\")\n        project.ext['signing.secretKeyRingFile'] = project.findProperty(\"signingSecretKeyRingFile\")","sourceCodeStart":154,"sourceCodeEnd":190,"githubUrl":"https://github.com/Tencent/tinker/blob/1b7ea02c239840f563ea64fb5bd286eb98d4011e/gradle/WeChatPublish.gradle#L154-L190","documentation":"Thrown by the private checkVersion() in gradle/WeChatPublish.gradle (line 172) during afterEvaluate-time publish configuration. It validates project.ext.fullVersion against the regex /\\d+\\.\\d+(?:\\.\\d+)?(?:\\.\\d+)?(?:\\.\\d+)?(?:-[\\w-]+)?/ — i.e. at least 'major.minor' (up to three extra numeric segments) plus an optional '-suffix'. When the version does not match and isSnapshot is false, it throws; when isSnapshot is true it only prints the message to stderr and continues. Note the regex is an unanchored Groovy ==~ match, so the whole string must match, meaning leading 'v', '+', spaces, or 'SNAPSHOT' instead of a '-suffix' form all fail.","triggerScenarios":"Calling the publish task (or any task that evaluates wechatPublish { version = ... }) with a release (isSnapshot=false) version such as '1.0.SNAPSHOT', 'v1.0.0', '1.0-beta.2' (dot in suffix — [\\w-]+ does not allow dots), '1.0 3', or an empty/unspecified version string that is not covered by the 'unspecified' -> '0.1' default. With isSnapshot=true the same input only produces the stderr warning and never throws.","commonSituations":"Migrating a Maven/Bintray version scheme ('1.0.0-SNAPSHOT' works only as suffix '-SNAPSHOT'? — actually '-SNAPSHOT' matches [\\w-]+, but '1.0.0.Final' or '1.0-beta.1' does not); setting version from a git tag like 'v2.1'; copying a semver prerelease with dots; forgetting to set version so a non-numeric placeholder leaks through.","solutions":["Set a version matching the pattern: major.minor with up to three optional numeric segments and an optional hyphenated suffix without dots, e.g. '1.2.3' or '1.2.3-RC1'.","Strip non-conforming decorations before assignment (e.g. remove a leading 'v' from a git tag: version = tag.substring(1)).","If the odd version is intentional and you only need a local snapshot build, leave isSnapshot = true (default) — the message is printed but no exception is thrown.","If you own the script, relax/anchor the regex, e.g. /\\d+(?:\\.\\d+){1,3}(?:-[\\w.\\-]+)?/."],"exampleFix":"// before\nwechatPublish {\n    version = 'v1.0-beta.2'\n    isSnapshot = false\n}\n\n// after\nwechatPublish {\n    version = '1.0.0-beta-2'\n    isSnapshot = false\n}","handlingStrategy":"validation","validationCode":"// before assigning, validate against the same pattern the script uses\ndef VERSION_RE = ~/\\d+\\.\\d+(?:\\.\\d+)?(?:\\.\\d+)?(?:\\.\\d+)?(?:-[\\w-]+)?/\nString v = /* your version source */ '1.2.3-RC1'\nassert v ==~ VERSION_RE : \"version '$v' will be rejected by WeChatPublish.checkVersion()\"","typeGuard":null,"tryCatchPattern":"try { /* publish task */ } catch (GradleException e) { if (e.message?.startsWith('Invalid version:')) { /* fix version, re-run */ } else throw e }","preventionTips":["Use plain 'major.minor[.patch]' with optional hyphen suffixes (no dots in the suffix, no leading 'v').","Validate the version string in CI before invoking publish tasks.","Remember isSnapshot=true only downgrades the throw to an stderr warning; do not rely on it to mask a bad release version."],"tags":["gradle","publishing","versioning","validation"],"backgroundTag":null,"analyzedSha":"1b7ea02c239840f563ea64fb5bd286eb98d4011e","analyzedAt":"2026-08-14T15:16:52.110Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}