affaan-m/ECC · error · Error
Nasiko manifest layer is not a qualified gzip artifact.
Error message
Nasiko manifest layer is not a qualified gzip artifact.
What it means
validateManifest requires the single OCI layer to have mediaType 'application/gzip' and a well-formed sha256 digest. This error is thrown when either check fails, meaning the layer is not the qualified gzip artifact the installer knows how to verify and extract.
Solutions
- Inspect layers[0].mediaType and compare against 'application/gzip'; republish the artifact with the required media type if you control the pipeline.
- Verify layers[0].digest matches /^sha256:[0-9a-f]{64}$/ and fix the publishing step that emits it.
- Confirm you are reading the OCI image manifest, not an index/manifest list whose entry shapes differ.
- Use a digest-pinned reference so you get the exact artifact version this library was built for.
Example fix
// before
validateManifest(manifestBytes); // throws: mediaType is tar+gzip
// after
const m = JSON.parse(manifestBytes.toString('utf8'));
const layer = m.layers[0];
if (layer.mediaType !== 'application/gzip') {
throw new Error(`republish required: got mediaType ${layer.mediaType}`);
}
validateManifest(manifestBytes); Defensive patterns
Strategy: validation
Validate before calling
const layer = JSON.parse(manifestBytes.toString('utf8')).layers[0];
if (layer.mediaType !== 'application/gzip' || !/^sha256:[0-9a-f]{64}$/.test(layer.digest)) throw new Error('layer not qualified gzip artifact'); Type guard
const isQualifiedGzipLayer = (l) => l?.mediaType === 'application/gzip' && typeof l?.digest === 'string' && /^sha256:[0-9a-f]{64}$/.test(l.digest); Try / catch
try { installNasiko(opts); } catch (e) { if (e.message.includes('not a qualified gzip artifact')) console.error('check publisher mediaType settings'); throw e; } Prevention
- Publish layers with mediaType application/gzip as the library requires.
- Snapshot-test your release manifest against the expected shape.
- Avoid generic container build tools that emit tar+gzip media types.
When it happens
Trigger: The manifest's layers[0].mediaType is something else (e.g. application/vnd.oci.image.layer.v1.tar+gzip, application/vnd.docker...tar, or application/octet-stream), or layers[0].digest fails SHA256_PATTERN (wrong prefix, uppercase, truncated).
Common situations: Publishing pipeline changed the layer compression or media type, artifact was built with docker instead of the OCI toolchain, or digest format drifted between publisher versions.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- Nasiko manifest layer size is outside the allowed range.
- Nasiko manifest must contain exactly one OCI layer.
- -32602
- a claim token is required
- a confirmed nonempty coordinate is required
AI-assisted analysis of affaan-m/ECC@8321021c54 (2026-09-16).
Data as JSON: /api/errors/cd6816bf4b503df7.
Report an issue: GitHub.
Appendix: source
Thrown at scripts/lib/nasiko-release.js:68
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) {
let manifest;
try { manifest = JSON.parse(bytes.toString('utf8')); } catch (_error) { throw new Error('Nasiko manifest is not valid JSON.'); }
if (manifest.schemaVersion !== 2 || !Array.isArray(manifest.layers) || manifest.layers.length !== 1) {
throw new Error('Nasiko manifest must contain exactly one OCI layer.');
}
const layer = manifest.layers[0];
if (layer.mediaType !== 'application/gzip' || !SHA256_PATTERN.test(layer.digest)) {
throw new Error('Nasiko manifest layer is not a qualified gzip artifact.');
}
if (!Number.isSafeInteger(layer.size) || layer.size <= 0 || layer.size > MAX_ARCHIVE_BYTES) {
throw new Error('Nasiko manifest layer size is outside the allowed range.');
}
return { digest: layer.digest, size: layer.size };
}
function readTarString(block, offset, length) {
return block.subarray(offset, offset + length).toString('utf8').replace(/\0.*$/, '');
}
function readTarOctal(block, offset, length) {
const field = block.subarray(offset, offset + length).toString('ascii');
const match = /^ *([0-7]+)[ \0]*$/.exec(field);
if (!match) throw new Error('Unsafe Nasiko archive: invalid tar size field.');
const size = Number.parseInt(match[1], 8);
if (!Number.isSafeInteger(size) || size < 0) {
throw new Error('Unsafe Nasiko archive: invalid tar size field.');View on GitHub (pinned to 8321021c54)