stablyai/orca · error

Adhoc build timestamp is invalid.

Error message

Adhoc build timestamp is invalid.

What it means

Thrown by createAdhocBuildVersion when the date argument is not a Date instance or is an Invalid Date (getTime() returns NaN). The adhoc version stamps UTC time down to the second, so a real timestamp is mandatory; this guard rejects undefined/null/numbers/strings and Date objects constructed from unparseable input.

Source

Thrown at config/scripts/adhoc-build-version.mjs:29

export const ADHOC_LABEL_MAX_LENGTH = 32

/**
 * `1.4.160-adhoc.20260728140533` — UTC to the second, so tags sort
 * chronologically by semver and every build is uniquely versioned.
 *
 * Why seconds when hourly uses minutes: hourly runs under a concurrency group and
 * cannot overlap itself. Adhoc builds are dispatched on demand, so two people
 * cutting from different branches in the same minute is ordinary — and a
 * minute-resolution tag would collide and fail the second build after its whole
 * pack-and-notarize run.
 */
export function createAdhocBuildVersion(baseVersion, date) {
  const match = /^(\d+\.\d+\.\d+)(?:-[0-9A-Za-z.-]+)?$/.exec(baseVersion)
  if (!match) {
    throw new Error(`Package version is not valid semver: ${baseVersion}`)
  }
  if (!(date instanceof Date) || Number.isNaN(date.getTime())) {
    throw new Error('Adhoc build timestamp is invalid.')
  }
  const pad = (value, width = 2) => String(value).padStart(width, '0')
  const stamp = [
    pad(date.getUTCFullYear(), 4),
    pad(date.getUTCMonth() + 1),
    pad(date.getUTCDate()),
    pad(date.getUTCHours()),
    pad(date.getUTCMinutes()),
    pad(date.getUTCSeconds())
  ].join('')
  // Why: drop any -rc.N tail, same as hourly. Keeping it would make every adhoc
  // build semver-NEWER than the RC it was cut from, letting an ordinary
  // RC-channel check offer an unreviewed branch build to RC users. Stripping to
  // the base parks adhoc below rc.N, hourly, and stable ('adhoc' sorts first
  // alphabetically), reachable only by an explicit pinned jump.
  return `${match[1]}-adhoc.${stamp}`
}

View on GitHub (pinned to 1136503c6a)

Solutions

  1. Pass a real Date: createAdhocBuildVersion(base, new Date()) or new Date(Date.now()).
  2. When constructing from an env-provided timestamp, parse it explicitly (e.g. new Date(ms) for an epoch) and validate before calling.
  3. Restore the default parameter 'now = new Date()' in getAdhocBuildIdentity if a refactor removed it.
  4. In tests, inject a frozen Date via sinon.useFakeTimers or a wrapper rather than passing a string.

Example fix

// before
// const id = getAdhocBuildIdentity('2026-07-28 14:05:33', label, published)
// -> 'Adhoc build timestamp is invalid.'

// after
// const id = getAdhocBuildIdentity(new Date('2026-07-28T14:05:33Z'), label, published)
Defensive patterns

Strategy: type-guard

Validate before calling

function assertValidTimestamp(date) {
  if (!(date instanceof Date) || Number.isNaN(date.getTime())) {
    throw new Error('Adhoc build timestamp must be a valid Date instance.')
  }
}
// assertValidTimestamp(date) before createAdhocBuildVersion

Type guard

function isValidTimestamp(value) {
  return value instanceof Date && !Number.isNaN(value.getTime())
}

Prevention

When it happens

Trigger: getAdhocBuildIdentity was called with a custom now that returned undefined; a test passed a string or epoch number instead of new Date(); the workflow injected a malformed timestamp through an env var that was wrapped in new Date(badString).

Common situations: Refactor changed the default parameter from new Date() to something else; ORCA timestamp env var formatted as 'YYYY-MM-DD HH:mm' (unparseable by Date constructor in some locales); mock clock returned null in a test.

Related errors


AI-assisted analysis of stablyai/orca@1136503c6a (2026-08-12). Data as JSON: /api/errors/807a7695f2f39e6c. Report an issue: GitHub.