Budibase/budibase · error · HTTPError
Project package is missing manifest.json.
Error message
Project package is missing manifest.json.
What it means
Every project package must include a manifest.json at the archive root. extractProjectPackage() probes for it with fsp.access and, when it is absent, throws this HTTP 400 at imports.ts:969-971. Without the manifest the importer cannot determine package metadata, so the import is rejected.
Source
Thrown at packages/server/src/sdk/workspace/projects/backups/imports.ts:970
![
PROJECT_MANIFEST_FILE,
PROJECT_FILE,
PROJECT_DEPENDENCY_INDEX_FILE,
PROJECT_DOCS_DIRECTORY,
].includes(entry)
)
) {
throw new HTTPError("Project package contains unsupported files.", 400)
}
const manifestPath = join(tmpPath, PROJECT_MANIFEST_FILE)
const projectPath = join(tmpPath, PROJECT_FILE)
const dependencyIndexPath = join(tmpPath, PROJECT_DEPENDENCY_INDEX_FILE)
const docsPath = join(tmpPath, PROJECT_DOCS_DIRECTORY)
await Promise.all([
fsp.access(manifestPath).catch(() => {
throw new HTTPError("Project package is missing manifest.json.", 400)
}),
fsp.access(projectPath).catch(() => {
throw new HTTPError("Project package is missing project.json.", 400)
}),
fsp.access(dependencyIndexPath).catch(() => {
throw new HTTPError(
"Project package is missing dependency-index.json.",
400
)
}),
])
const [manifest, project, dependencyIndex] = await Promise.all([
readJsonFile<ProjectPackageManifest>(manifestPath),
readJsonFile<Project>(projectPath),
readJsonFile<ProjectPackageDependencyIndex>(dependencyIndexPath),
])
View on GitHub (pinned to a81a902e9a)
Solutions
- Re-export the project package from the source workspace so a valid manifest.json is included
- Verify the archive actually contains manifest.json at the root (tar -tf pkg.tgz | grep manifest)
- If unarchiving/re-archiving manually, don't drop manifest.json from the root
- Re-download the package — the original may have been truncated or corrupted in transit
Example fix
null
Defensive patterns
Strategy: validation
Validate before calling
import { createReadStream } from 'fs'
import { parse } from 'tar'
const hasManifest = await new Promise<boolean>((resolve, reject) => {
const ws = parse({ onReadEntry: (e: any) => { if (e.path === 'manifest.json') { resolve(true); ws.abort?.() } }, onEnd: () => resolve(false) })
createReadStream(packagePath).pipe(ws as any)
ws.on('error', reject)
})
if (!hasManifest) throw new Error('package is missing manifest.json at archive root') Type guard
function hasRequiredRootFiles(entries: readonly string[]): entries is readonly string[] {
const required = ['manifest.json', 'project.json', 'dependency-index.json']
return required.every(f => entries.includes(f))
} Try / catch
try {
await importProjectPackage(file)
} catch (err) {
if (err instanceof HTTPError && err.status === 400 && err.message === 'Project package is missing manifest.json.') {
// obtain a complete package: re-export from the source workspace
} else {
throw err
}
} Prevention
- Verify package contents (manifest.json, project.json, dependency-index.json, docs) before import
- Avoid unarchive/re-archive round trips that can drop root files
- Check download completion (size/checksum) to catch truncated archives
- Prefer fresh exports over stored/copy-pasted package files
When it happens
Trigger: Importing a package tarball whose root has no manifest.json — the fsp.access(manifestPath) promise rejects at imports.ts:968-971 inside the Promise.all validation.
Common situations: Importing an archive of just project docs or a partial extraction; hand-assembling a package and forgetting the manifest; a truncated or corrupted tarball missing entries; importing an artifact type that never had a manifest.
Related errors
- Project package is missing project.json.
- Project package is missing dependency-index.json.
- Project package is too large.
- Unsupported Project doc path '${relPath}'.
- Project package contains a doc without an id.
AI-assisted analysis of Budibase/budibase@a81a902e9a (2026-08-29).
Data as JSON: /api/errors/72bb7397ac97b1e0.
Report an issue: GitHub.