{"record":{"id":"21287bd235e9c5f8","repo":"stablyai/orca","slug":"package-version-is-not-valid-semver-baseversion-21287b","errorCode":null,"errorMessage":"Package version is not valid semver: ${baseVersion}","messagePattern":"Package version is not valid semver: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"config/scripts/hourly-build-version.mjs","lineNumber":15,"sourceCode":"import { execFileSync } from 'node:child_process'\nimport { readFileSync } from 'node:fs'\nimport { resolve } from 'node:path'\nimport { formatReleaseTitleTimestamp } from './release-title-timestamp.mjs'\nimport {\n  readPublishedVersionsFromEnv,\n  resolveDevChannelBaseVersion\n} from './dev-channel-base-version.mjs'\n\n/** `1.4.160-hourly.202607281400` — UTC to the minute, so tags sort chronologically\n *  by semver and every build is uniquely versioned. */\nexport function createHourlyBuildVersion(baseVersion, date) {\n  const match = /^(\\d+\\.\\d+\\.\\d+)(?:-[0-9A-Za-z.-]+)?$/.exec(baseVersion)\n  if (!match) {\n    throw new Error(`Package version is not valid semver: ${baseVersion}`)\n  }\n  if (!(date instanceof Date) || Number.isNaN(date.getTime())) {\n    throw new Error('Hourly build timestamp is invalid.')\n  }\n  const pad = (value, width = 2) => String(value).padStart(width, '0')\n  const stamp = [\n    pad(date.getUTCFullYear(), 4),\n    pad(date.getUTCMonth() + 1),\n    pad(date.getUTCDate()),\n    pad(date.getUTCHours()),\n    pad(date.getUTCMinutes())\n  ].join('')\n  // Why: drop any -rc.N tail. Keeping it makes every hourly semver-NEWER than the\n  // RC it was cut from (1.4.160-rc.3-hourly.X > 1.4.160-rc.3), which would let an\n  // ordinary RC-channel check offer untested hourly builds to RC users. Stripping\n  // to the base parks hourlies below both rc.N and stable ('hourly' < 'rc'\n  // alphabetically), reachable only by an explicit pinned jump.\n  return `${match[1]}-hourly.${stamp}`","sourceCodeStart":1,"sourceCodeEnd":33,"githubUrl":"https://github.com/stablyai/orca/blob/1136503c6a231a16dce8f921f6fadb63d181e8db/config/scripts/hourly-build-version.mjs#L1-L33","documentation":"Thrown by createHourlyBuildVersion() when baseVersion does not match the regex `/^(\\d+\\.\\d+\\.\\d+)(?:-[0-9A-Za-z.-]+)?$/`. This accepts a stable x.y.z or a prerelease-tagged x.y.z-something, rejecting anything that is not valid semver-ish (build metadata with '+', leading 'v', missing patch, etc.). baseVersion normally comes from package.json's version field (via resolveDevChannelBaseVersion).","triggerScenarios":"package.json version is malformed (e.g. '1.4', 'v1.4.0', '1.4.0+sha'), or a caller passes a non-semver string into createHourlyBuildVersion directly.","commonSituations":"A bad manual edit to package.json version, a release tool writing a non-standard version string, or calling the function with a raw git tag/branch name instead of a resolved base version.","solutions":["Ensure package.json version is valid semver (x.y.z or x.y.z-prerelease): e.g. `1.4.160` or `1.4.160-rc.1`.","If passing a value directly, strip leading 'v' and build metadata ('+...') before calling.","Validate with a semver library before invoking if the source is untrusted."],"exampleFix":"// before\ncreateHourlyBuildVersion('v1.4.0', new Date())  // throws\n// after\ncreateHourlyBuildVersion('1.4.0', new Date())","handlingStrategy":"validation","validationCode":"import semver from 'semver'\nfunction assertBaseVersion(v: string) {\n  if (!semver.valid(v)) throw new Error(`Package version is not valid semver: ${v}`)\n}\nassertBaseVersion(baseVersion)","typeGuard":"const isValidBaseVersion = (v: unknown): v is string =>\n  typeof v === 'string' && /^(\\d+\\.\\d+\\.\\d+)(?:-[0-9A-Za-z.-]+)?$/.test(v)","tryCatchPattern":null,"preventionTips":["Keep package.json version in strict x.y.z or x.y.z-prerelease form.","Strip leading 'v' and '+build' metadata before passing a version into createHourlyBuildVersion.","Add a lint check on package.json version in CI."],"tags":["release","semver","versioning","validation"],"backgroundTag":null,"analyzedSha":"1136503c6a231a16dce8f921f6fadb63d181e8db","analyzedAt":"2026-08-12T23:15:58.167Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}