{"record":{"id":"34a81ea467157bec","repo":"microsoft/typescript-go","slug":"prerelease-version-should-be-in-the-form-of-dev-n","errorCode":null,"errorMessage":"Prerelease version should be in the form of dev.<number>.<number>, but got ${prerelease}","messagePattern":"Prerelease version should be in the form of dev\\.<number>\\.<number>, but got (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"Herebyfile.mjs","lineNumber":2327,"sourceCode":"    if (!extensions.length) {\r\n        console.log(\"No VSIX targets configured; skipping extension packaging.\");\r\n        return;\r\n    }\r\n\r\n    // We don't use vscode:prepublish, as that would run the build for each package below.\r\n    await $({ cwd: extensionDir, env: releasePackageEnv })`npm run bundle:release`;\r\n\r\n    let version = \"0.0.0\";\r\n    if (options.forRelease) {\r\n        // No real semver prerelease versioning.\r\n        // https://code.visualstudio.com/api/working-with-extensions/publishing-extension#prerelease-extensions\r\n        assert(options.setPrerelease, \"forRelease is true but setPrerelease is not set\");\r\n        const prerelease = options.setPrerelease;\r\n        assert(typeof prerelease === \"string\", \"setPrerelease is not a string\");\r\n        // parse `dev.<number>.<number>`.\r\n        const match = prerelease.match(/dev\\.(\\d+)\\.(\\d+)/);\r\n        if (!match) {\r\n            throw new Error(`Prerelease version should be in the form of dev.<number>.<number>, but got ${prerelease}`);\r\n        }\r\n        // Set version to `0.<number>.<number>`.\r\n        version = `0.${match[1]}.${match[2]}`;\r\n    }\r\n\r\n    console.log(\"Version:\", version);\r\n\r\n    await Promise.all(extensions.map(async ({ npmDir, npmPackageName, nodeOs, vscodeTarget, sourceDir, extensionDir: thisExtensionDir, vsixPath, vsixManifestPath, vsixSignaturePath }) => {\r\n        const npmLibDir = usePublishedPlatformPackagesForVsix\r\n            ? await getPublishedPlatformPackageLibDir(npmPackageName)\r\n            : path.join(npmDir, \"lib\");\r\n        const extensionLibDir = path.join(thisExtensionDir, \"lib\");\r\n        await fs.promises.mkdir(extensionLibDir, { recursive: true });\r\n\r\n        await cpWithoutNodeModulesOrTsconfig(sourceDir, thisExtensionDir);\r\n        await cpWithoutNodeModulesOrTsconfig(npmLibDir, extensionLibDir);\r\n        await fs.promises.chmod(path.join(extensionLibDir, nativePreviewExeName(nodeOs)), 0o755);\r\n\r","sourceCodeStart":2309,"sourceCodeEnd":2345,"githubUrl":"https://github.com/microsoft/typescript-go/blob/1bcfa18d79a3be41772223d5c05dfe4480e614ff/Herebyfile.mjs#L2309-L2345","documentation":"In runPackVsixExtensions, the release path requires a prerelease identifier of the exact form `dev.<number>.<number>` (regex `dev\\.(\\d+)\\.(\\d+)`) because VS Code has no real semver prerelease channel — the extension version is mechanically rewritten to `0.<number>.<number>` (VS Code then treats 0.x pre-releases correctly). Anything not matching (dev, dev.1, beta.1.0, 1.2.3) is rejected.","triggerScenarios":"Running `npx hereby native-preview:release --forRelease` (or the VSIX pack task) with a --setPrerelease value that doesn't match `dev.N.M`, e.g. `--setPrerelease=dev`, `--setPrerelease=dev.1`, or `--setPrerelease=beta.1.0`. Note the preceding asserts also require setPrerelease to be present and a string.","commonSituations":"CI templates the flag from a variable that produces a different format; a developer assumes semver prerelease syntax is allowed; the flag is simply forgotten (caught earlier by the assert).","solutions":["Pass the prerelease in the required form, e.g. `--setPrerelease=dev.1.0`","Fix the CI/release script that assembles the value so it always emits `dev.<int>.<int>`","Remember the two numbers map directly to the VSIX version's minor/patch (0.N.M) — choose them per the nightly counter you want"],"exampleFix":"# before\nnpx hereby native-preview:release --forRelease --setPrerelease=beta.1.0\n\n# after\nnpx hereby native-preview:release --forRelease --setPrerelease=dev.1.0","handlingStrategy":"validation","validationCode":"const m = prerelease.match(/^dev\\.(\\d+)\\.(\\d+)$/);\nif (!m) {\n  throw new Error(`setPrerelease must be dev.<int>.<int>, got \"${prerelease}\"`);\n}\nconst vsixVersion = `0.${m[1]}.${m[2]}`;","typeGuard":"function isDevPrerelease(v: string): v is `dev.${number}.${number}` {\n  return /^dev\\.\\d+\\.\\d+$/.test(v);\n}","tryCatchPattern":null,"preventionTips":["Generate --setPrerelease from a counter in CI rather than typing it by hand","Validate the format in the release script before invoking hereby"],"tags":["release","versioning","vsix","hereby"],"backgroundTag":null,"analyzedSha":"1bcfa18d79a3be41772223d5c05dfe4480e614ff","analyzedAt":"2026-08-16T02:12:00.115Z","schemaVersion":2},"datasetVersion":"2026-08-16T03:17:38.424Z"}