{"record":{"id":"fbe8459e6ec9f3b2","repo":"Yeachan-Heo/oh-my-codex","slug":"native-assets-package-json-is-missing-version","errorCode":null,"errorMessage":"[native-assets] package.json is missing version","messagePattern":"\\[native-assets\\] package\\.json is missing version","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/cli/native-assets.ts","lineNumber":74,"sourceCode":"const NATIVE_MANIFEST_URL_ENV = 'OMX_NATIVE_MANIFEST_URL';\nconst NATIVE_RELEASE_BASE_URL_ENV = 'OMX_NATIVE_RELEASE_BASE_URL';\nconst NATIVE_CACHE_DIR_ENV = 'OMX_NATIVE_CACHE_DIR';\nexport const EXPLORE_BIN_ENV = 'OMX_EXPLORE_BIN';\nexport const SPARKSHELL_BIN_ENV = 'OMX_SPARKSHELL_BIN';\nexport const API_BIN_ENV = 'OMX_API_BIN';\n\nfunction packageJsonPath(packageRoot = getPackageRoot()): string {\n  return join(packageRoot, 'package.json');\n}\n\nasync function readPackageJson(packageRoot = getPackageRoot()): Promise<{ version?: string; repository?: { url?: string } | string }> {\n  const raw = await readFile(packageJsonPath(packageRoot), 'utf-8');\n  return JSON.parse(raw) as { version?: string; repository?: { url?: string } | string };\n}\n\nexport async function getPackageVersion(packageRoot = getPackageRoot()): Promise<string> {\n  const pkg = await readPackageJson(packageRoot);\n  if (!pkg.version?.trim()) throw new Error('[native-assets] package.json is missing version');\n  return pkg.version.trim();\n}\n\nfunction repositoryHttpBase(repository: { url?: string } | string | undefined): string | undefined {\n  const raw = typeof repository === 'string' ? repository : repository?.url;\n  if (!raw?.trim()) return undefined;\n  const trimmed = raw.trim().replace(/^git\\+/, '').replace(/\\.git$/, '');\n  if (trimmed.startsWith('https://github.com/')) return trimmed;\n  if (trimmed.startsWith('http://github.com/')) return trimmed.replace(/^http:/, 'https:');\n  return undefined;\n}\n\nexport async function resolveNativeReleaseBaseUrl(\n  packageRoot = getPackageRoot(),\n  version?: string,\n  env: NodeJS.ProcessEnv = process.env,\n): Promise<string> {\n  const override = env[NATIVE_RELEASE_BASE_URL_ENV]?.trim();","sourceCodeStart":56,"sourceCodeEnd":92,"githubUrl":"https://github.com/Yeachan-Heo/oh-my-codex/blob/3ad79a8a6fe6e95fdbb8c00e40716fffe4011ce2/src/cli/native-assets.ts#L56-L92","documentation":"getPackageVersion reads the package's package.json and throws when the version field is missing or whitespace-only. The native-assets machinery needs the version to compute asset paths/names, so an absent version is fatal.","triggerScenarios":"A package.json without a version field, version: \"\", or version: \"   \"; a build/packaging step that strips or placeholder-fies the version; calling getPackageVersion with a packageRoot pointing at a directory whose package.json lacks version.","commonSituations":"Private workspace packages where version was omitted; publish pipelines that inject version at a later stage; monorepo tooling generating package.json without version; wrong packageRoot resolution.","solutions":["Add a valid semver version field to package.json (even 0.0.0 for private packages)","Verify getPackageVersion is called with the correct packageRoot","If version is injected at publish time, inject it before native asset resolution runs"],"exampleFix":"// before\n{ \"name\": \"pkg\", \"private\": true }\n// after\n{ \"name\": \"pkg\", \"version\": \"0.0.0\", \"private\": true }","handlingStrategy":"type-guard","validationCode":"const pkg = JSON.parse(await readFile('package.json', 'utf-8'));\nif (!pkg.version?.trim()) failEarly('package.json needs a version');","typeGuard":"function hasVersion(pkg: { version?: string }): pkg is { version: string } {\n  return typeof pkg.version === 'string' && pkg.version.trim().length > 0;\n}","tryCatchPattern":null,"preventionTips":["Set version: 0.0.0 in private packages","Run getPackageVersion early in build to fail fast on manifest problems"],"tags":["packaging","manifest","version"],"backgroundTag":"missing-package-manifest-field","analyzedSha":"3ad79a8a6fe6e95fdbb8c00e40716fffe4011ce2","analyzedAt":"2026-08-27T22:18:39.783Z","schemaVersion":2},"datasetVersion":"2026-08-28T00:17:15.603Z"}