Yeachan-Heo/oh-my-codex · error · Error
[native-assets] package.json is missing version
Error message
[native-assets] package.json is missing version
What it means
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.
Source
Thrown at src/cli/native-assets.ts:74
const NATIVE_MANIFEST_URL_ENV = 'OMX_NATIVE_MANIFEST_URL';
const NATIVE_RELEASE_BASE_URL_ENV = 'OMX_NATIVE_RELEASE_BASE_URL';
const NATIVE_CACHE_DIR_ENV = 'OMX_NATIVE_CACHE_DIR';
export const EXPLORE_BIN_ENV = 'OMX_EXPLORE_BIN';
export const SPARKSHELL_BIN_ENV = 'OMX_SPARKSHELL_BIN';
export const API_BIN_ENV = 'OMX_API_BIN';
function packageJsonPath(packageRoot = getPackageRoot()): string {
return join(packageRoot, 'package.json');
}
async function readPackageJson(packageRoot = getPackageRoot()): Promise<{ version?: string; repository?: { url?: string } | string }> {
const raw = await readFile(packageJsonPath(packageRoot), 'utf-8');
return JSON.parse(raw) as { version?: string; repository?: { url?: string } | string };
}
export async function getPackageVersion(packageRoot = getPackageRoot()): Promise<string> {
const pkg = await readPackageJson(packageRoot);
if (!pkg.version?.trim()) throw new Error('[native-assets] package.json is missing version');
return pkg.version.trim();
}
function repositoryHttpBase(repository: { url?: string } | string | undefined): string | undefined {
const raw = typeof repository === 'string' ? repository : repository?.url;
if (!raw?.trim()) return undefined;
const trimmed = raw.trim().replace(/^git\+/, '').replace(/\.git$/, '');
if (trimmed.startsWith('https://github.com/')) return trimmed;
if (trimmed.startsWith('http://github.com/')) return trimmed.replace(/^http:/, 'https:');
return undefined;
}
export async function resolveNativeReleaseBaseUrl(
packageRoot = getPackageRoot(),
version?: string,
env: NodeJS.ProcessEnv = process.env,
): Promise<string> {
const override = env[NATIVE_RELEASE_BASE_URL_ENV]?.trim();View on GitHub (pinned to 3ad79a8a6f)
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
Example fix
// before
{ "name": "pkg", "private": true }
// after
{ "name": "pkg", "version": "0.0.0", "private": true } Defensive patterns
Strategy: type-guard
Validate before calling
const pkg = JSON.parse(await readFile('package.json', 'utf-8'));
if (!pkg.version?.trim()) failEarly('package.json needs a version'); Type guard
function hasVersion(pkg: { version?: string }): pkg is { version: string } {
return typeof pkg.version === 'string' && pkg.version.trim().length > 0;
} Prevention
- Set version: 0.0.0 in private packages
- Run getPackageVersion early in build to fail fast on manifest problems
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- catalog_manifest_missing
- catalog_manifest_invalid:schemaVersion
- autoresearch_resume_manifest_missing
- catalog_manifest_invalid:${field}
- catalog_manifest_invalid:root
AI-assisted analysis of Yeachan-Heo/oh-my-codex@3ad79a8a6f (2026-08-27).
Data as JSON: /api/errors/fbe8459e6ec9f3b2.
Report an issue: GitHub.