nocobase/nocobase · error · Error

failed to extract ${NOCOBASE_SKILLS_PACKAGE_NAME} tarball: $

Error message

failed to extract ${NOCOBASE_SKILLS_PACKAGE_NAME} tarball: ${message}

What it means

Wrapper error: any failure during tarball extraction or moving the extract root into place (spawn of tar, read/parse errors, rename across devices, mkdir/rm failures) is caught, the partial extractRoot is cleaned up, and rethrown with this prefix plus the underlying message. The original cause is embedded in the message text.

Source

Thrown at packages/core/cli/src/lib/skills-manager.ts:388

          packageName || '(missing package name)'
        } instead of ${NOCOBASE_SKILLS_PACKAGE_NAME}.`,
      );
    }

    if (targetVersion && packageVersion !== targetVersion) {
      throw new Error(
        `packed tarball resolved to version ${packageVersion || '(missing version)'} instead of ${targetVersion}.`,
      );
    }

    await fsp.rm(packageDir, { recursive: true, force: true });
    await fsp.mkdir(path.dirname(packageDir), { recursive: true });
    await fsp.rename(extractRoot, packageDir);
    return packageDir;
  } catch (error: unknown) {
    await fsp.rm(extractRoot, { recursive: true, force: true });
    const message = error instanceof Error ? error.message : String(error);
    throw new Error(`failed to extract ${NOCOBASE_SKILLS_PACKAGE_NAME} tarball: ${message}`);
  }
}

async function prepareLocalSkillsPackage(
  globalRoot: string,
  options: SkillsSyncOptions = {},
  targetVersion?: string,
): Promise<{ packageDir: string; cleanup: () => Promise<void> }> {
  const cacheRoot = getSkillsCacheRoot(globalRoot);
  const packageDir = getCachedSkillsPackageDir(cacheRoot);
  const packRoot = getCachedSkillsPackRoot(cacheRoot);
  const packageSpec = targetVersion ? `${NOCOBASE_SKILLS_PACKAGE_NAME}@${targetVersion}` : NOCOBASE_SKILLS_PACKAGE_NAME;
  const cachedVersion = await readCachedSkillsVersion(cacheRoot);

  await fsp.mkdir(cacheRoot, { recursive: true });

  if (targetVersion && cachedVersion && compareVersions(cachedVersion, targetVersion) === 0) {
    options.onProgress?.(`Using cached ${NOCOBASE_SKILLS_PACKAGE_NAME}@${targetVersion}...`);

View on GitHub (pinned to fa42722fef)

Solutions

  1. Read the suffixed cause in the message and fix it directly (e.g. re-pack if the tarball is corrupt, install tar if missing).
  2. Delete the skills cache/package directory and re-run the sync from scratch.
  3. Point the cache/package directory to the same filesystem as the extraction root to avoid EXDEV rename errors.
  4. Check free disk space and write permissions on the target directories.

Example fix

// before
// rename across devices: EXDEV
packageDir = '/mnt/external/skills'; extractRoot = '/tmp/skills-xxx';
// after
// keep both on the same filesystem
packageDir = '/tmp/cache/skills'; extractRoot = '/tmp/skills-xxx';
Defensive patterns

Strategy: try-catch

Validate before calling

import { access } from 'node:fs/promises';
await access(tarballPath); // ensure tarball exists and is readable before extraction
// also confirm `tar` availability in minimal containers

Try / catch

try {
  await prepareLocalSkillsPackage(/*...*/);
} catch (err) {
  if (err.message.startsWith('failed to extract')) {
    const cause = err.message.split(': ').slice(1).join(': '); // inspect underlying cause
    // clear cache dir and retry once
  }
}

Prevention

When it happens

Trigger: extractPackedSkillsTarball's try block throws — e.g. the .tgz is corrupt or not gzip, the tar binary is missing, fsp.rename fails across filesystems, or disk is full — after the name/version checks.

Common situations: Truncated/partial tarball from an interrupted pack; no `tar` available in a minimal container; /tmp on a different mount than the package dir causing EXDEV on rename; permissions issues in the cache root.

Related errors


AI-assisted analysis of nocobase/nocobase@fa42722fef (2026-09-01). Data as JSON: /api/errors/616e7608d4b0ded2. Report an issue: GitHub.