affaan-m/ECC · error · Error
Nasiko installation requires a pinned version such as…
Error message
Nasiko installation requires a pinned version such as v0.1.0; latest is not allowed.
What it means
getQualifiedRelease requires an exact semver version string in the form vX.Y.Z because Nasiko installs are pinned to cryptographically qualified releases. 'latest', loose versions ('0.1.0' without 'v'), ranges, or empty input throw, ensuring digest pinning is always explicit.
Solutions
- Use an exact pinned tag like v0.1.0
- Strip/add the 'v' prefix to match ^v\d+\.\d+\.\d+$
- Check QUALIFIED_RELEASES in scripts/lib/nasiko-release.js for versions that exist
- Resolve 'latest' manually by looking up the newest release tag first
Example fix
// before
getQualifiedRelease('latest');
// after
getQualifiedRelease('v0.1.0'); Defensive patterns
Strategy: validation
Validate before calling
const VERSION_RE = /^v\d+\.\d+\.\d+$/;
if (!VERSION_RE.test(String(version ?? ''))) {
throw new Error(`version must match vX.Y.Z, got: ${version}`);
} Type guard
function isPinnedVersion(v) {
return typeof v === 'string' && /^v\d+\.\d+\.\d+$/.test(v);
} Try / catch
try {
const rel = getQualifiedRelease(version);
} catch (e) {
if (e.message.includes('pinned version')) {
console.error('Resolve latest to a concrete tag, e.g. v0.1.0, and retry.');
} else throw e;
} Prevention
- Never use 'latest' for digest-pinned installers
- Normalize version sources (package.json tags often lack the leading 'v')
- Store the pinned version in config, not env that may be empty
When it happens
Trigger: Passing 'latest', 'v0.1', '0.1.0', 'v0.1.0-beta', or an unset version into getQualifiedRelease (directly or via the Nasiko install command/config).
Common situations: Using 'latest' out of habit from npm; reading a version from package.json that lacks the 'v' prefix; config/env interpolation producing an empty version; attempting a prerelease build.
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
Related errors
- Nasiko is not qualified for / .
- Unsupported asset receipt schema
- Unsupported canonical session schema version
- -32602
- a claim token is required
AI-assisted analysis of affaan-m/ECC@8321021c54 (2026-09-16).
Data as JSON: /api/errors/5e9fa5caa305c585.
Report an issue: GitHub.
Appendix: source
Thrown at scripts/lib/nasiko-release.js:42
'linux/arm64': Object.freeze({ manifestDigest: 'sha256:655021a129c7df4621a80d16ea4eab38018530bfe9a20da646641d9f4ac5c249', binaryDigest: 'sha256:85f9fa5cfbed6c276fce6df2d71e9d0c66d7d8e8d46a40297464833d38db7a7e' }),
'darwin/amd64': Object.freeze({ manifestDigest: 'sha256:b4188482621efd7da5a2ab630f653665ab5f80b9aceae448b6bb5fc93e003f06', binaryDigest: 'sha256:ed6232e0bb96a2dcfd86d3c25f86021091600d52f09250403a54528bfe8100a3' }),
'darwin/arm64': Object.freeze({ manifestDigest: 'sha256:ce7e54fa19f989a5d125c4409b3587ca9503bb5a07bc5ff223c60e0fbad437f0', binaryDigest: 'sha256:3c60f862b04eea1b9a633593b39f1a443d9ca2123cf3edfd150d313e95f3894b' }),
'windows/amd64': Object.freeze({ manifestDigest: 'sha256:0760fe1fc98e8fedb66796aaf891a1de9268af1338c5e88b949656fda5d9f045', binaryDigest: 'sha256:0f57672d24fc3c70e4cbbf22864e65b35b9978ddaae3793803841536e682929b' }),
}),
});
function normalizePlatform(platform = process.platform, architecture = process.arch) {
const osName = platform === 'win32' ? 'windows' : platform;
if (!['linux', 'darwin', 'windows'].includes(osName)) throw new Error(`Unsupported platform: ${platform}`);
const arch = architecture === 'x64' ? 'amd64' : architecture;
if (!['amd64', 'arm64'].includes(arch)) throw new Error(`Unsupported architecture: ${architecture}`);
if (osName === 'windows' && arch !== 'amd64') throw new Error(`Unsupported architecture for Windows: ${architecture}`);
return { os: osName, arch, binaryName: osName === 'windows' ? 'nasiko.exe' : 'nasiko' };
}
function getQualifiedRelease(version, platform = process.platform, architecture = process.arch) {
if (!/^v\d+\.\d+\.\d+$/.test(String(version || ''))) {
throw new Error('Nasiko installation requires a pinned version such as v0.1.0; latest is not allowed.');
}
const normalized = normalizePlatform(platform, architecture);
const qualification = QUALIFIED_RELEASES[version]?.[`${normalized.os}/${normalized.arch}`];
if (!qualification) throw new Error(`Nasiko ${version} is not qualified for ${normalized.os}/${normalized.arch}.`);
return { version, ...normalized, ...qualification, license: LICENSE, sourceUrl: SOURCE_URL };
}
function digestBytes(bytes) {
return `sha256:${crypto.createHash('sha256').update(bytes).digest('hex')}`;
}
function assertDigest(bytes, expectedDigest, label) {
if (!SHA256_PATTERN.test(expectedDigest)) throw new Error(`${label} has an invalid expected digest.`);
const actual = digestBytes(bytes);
if (actual !== expectedDigest) throw new Error(`${label} digest mismatch: expected ${expectedDigest}, got ${actual}.`);
}
function validateManifest(bytes) {View on GitHub (pinned to 8321021c54)