{"record":{"id":"c601db4f830dc042","repo":"affaan-m/ECC","slug":"nasiko-version-is-not-qualified-for-normalize","errorCode":null,"errorMessage":"Nasiko ${version} is not qualified for ${normalized.os}/${normalized.arch}.","messagePattern":"Nasiko (.+?) is not qualified for (.+?)/(.+?)\\.","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"scripts/lib/nasiko-release.js","lineNumber":46,"sourceCode":"  }),\n});\n\nfunction normalizePlatform(platform = process.platform, architecture = process.arch) {\n  const osName = platform === 'win32' ? 'windows' : platform;\n  if (!['linux', 'darwin', 'windows'].includes(osName)) throw new Error(`Unsupported platform: ${platform}`);\n  const arch = architecture === 'x64' ? 'amd64' : architecture;\n  if (!['amd64', 'arm64'].includes(arch)) throw new Error(`Unsupported architecture: ${architecture}`);\n  if (osName === 'windows' && arch !== 'amd64') throw new Error(`Unsupported architecture for Windows: ${architecture}`);\n  return { os: osName, arch, binaryName: osName === 'windows' ? 'nasiko.exe' : 'nasiko' };\n}\n\nfunction getQualifiedRelease(version, platform = process.platform, architecture = process.arch) {\n  if (!/^v\\d+\\.\\d+\\.\\d+$/.test(String(version || ''))) {\n    throw new Error('Nasiko installation requires a pinned version such as v0.1.0; latest is not allowed.');\n  }\n  const normalized = normalizePlatform(platform, architecture);\n  const qualification = QUALIFIED_RELEASES[version]?.[`${normalized.os}/${normalized.arch}`];\n  if (!qualification) throw new Error(`Nasiko ${version} is not qualified for ${normalized.os}/${normalized.arch}.`);\n  return { version, ...normalized, ...qualification, license: LICENSE, sourceUrl: SOURCE_URL };\n}\n\nfunction digestBytes(bytes) {\n  return `sha256:${crypto.createHash('sha256').update(bytes).digest('hex')}`;\n}\n\nfunction assertDigest(bytes, expectedDigest, label) {\n  if (!SHA256_PATTERN.test(expectedDigest)) throw new Error(`${label} has an invalid expected digest.`);\n  const actual = digestBytes(bytes);\n  if (actual !== expectedDigest) throw new Error(`${label} digest mismatch: expected ${expectedDigest}, got ${actual}.`);\n}\n\nfunction validateManifest(bytes) {\n  let manifest;\n  try { manifest = JSON.parse(bytes.toString('utf8')); } catch (_error) { throw new Error('Nasiko manifest is not valid JSON.'); }\n  if (manifest.schemaVersion !== 2 || !Array.isArray(manifest.layers) || manifest.layers.length !== 1) {\n    throw new Error('Nasiko manifest must contain exactly one OCI layer.');","sourceCodeStart":28,"sourceCodeEnd":64,"githubUrl":"https://github.com/affaan-m/ECC/blob/06c5e118c4d3e6c3b7f9445f973a2194c82de193/scripts/lib/nasiko-release.js#L28-L64","documentation":"getQualifiedRelease in scripts/lib/nasiko-release.js looks up the pinned digest table QUALIFIED_RELEASES[version][`${os}/${arch}`] after the version passed the 'vX.Y.Z' regex and the platform was normalized. An undefined result means either the version has no entry at all, or the version exists but lacks a build for this os/arch pair. Only versions whose digests were qualified at the time this file was shipped can install.","triggerScenarios":"Passing a well-formed version that is absent from the table, e.g. 'v0.2.0' against a checkout that only knows 'v0.1.0'; or a version that exists but has no build for the normalized pair, e.g. 'v0.1.0' on a combination the table omits. Note windows/arm64 is intercepted earlier by the dedicated check in normalizePlatform.","commonSituations":"A new Nasiko release was tagged upstream but the ECC copy of this script predates it; hardcoding a future version in config; a typo that still matches semver like 'v0.0.1'; forks that add versions to their registry but not to QUALIFIED_RELEASES.","solutions":["Use a version present in the table, currently 'v0.1.0'","Update the ECC checkout so scripts/lib/nasiko-release.js carries the newest QUALIFIED_RELEASES entries for the version you want","If you maintain the tool, add the new version's per-platform manifestDigest/binaryDigest entries when releasing"],"exampleFix":"// before: version not in the qualified table\ninstallNasiko({ version: 'v0.2.0' }); // throws\n// after\ninstallNasiko({ version: 'v0.1.0' });","handlingStrategy":"validation","validationCode":"// Mirror the qualified matrix the script ships with; update alongside upgrades.\nconst QUALIFIED = new Set(['v0.1.0']);\nconst QUALIFIED_PAIRS = new Set([\n  'v0.1.0:linux/amd64', 'v0.1.0:linux/arm64',\n  'v0.1.0:darwin/amd64', 'v0.1.0:darwin/arm64', 'v0.1.0:windows/amd64',\n]);\nconst os = process.platform === 'win32' ? 'windows' : process.platform;\nconst arch = process.arch === 'x64' ? 'amd64' : process.arch;\nif (!QUALIFIED_PAIRS.has(`${version}:${os}/${arch}`)) version = 'v0.1.0';","typeGuard":null,"tryCatchPattern":"try {\n  await installNasiko({ version });\n} catch (error) {\n  if (/is not qualified for/.test(String(error.message))) {\n    // Fall back to a known-qualified version (v0.1.0) or update the checkout.\n  }\n  throw error;\n}","preventionTips":["Keep your pinned version in lockstep with the QUALIFIED_RELEASES table in your ECC revision","After bumping the version constant, grep nasiko-release.js for the new tag's digests","Fail fast in CI on unknown version/platform combinations instead of at install time"],"tags":["version","platform-matrix","supply-chain"],"backgroundTag":"version-platform-not-supported","analyzedSha":"06c5e118c4d3e6c3b7f9445f973a2194c82de193","analyzedAt":"2026-08-18T11:27:13.915Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T05:18:18.240Z"}