chatboxai/chatbox · error
Resource was not staged: ${resource.path}
Error message
Resource was not staged: ${resource.path} What it means
Thrown by createResourcePlans when a manifest resource's path has no staged entry or its staged entry lacks a tempKey. Reading normally stages every resource under a temp blob key (lines 244-248); reaching this throw means staging and the manifest disagree. Propagates after rollback.
Source
Thrown at src/renderer/packages/backup/import-backup.ts:137
}
}
const candidate = `${candidatePrefix}:${uuidv4()}`
if (!reserved.has(candidate) && (await storage.getBlob(candidate)) === null) return candidate
}
throw new Error(`Could not allocate a resource key for: ${originalKey}`)
}
async function createResourcePlans(
manifest: BackupManifest,
stagedEntries: Map<string, StagedEntry>,
storage: BackupStorage
) {
const plans: ResourceWritePlan[] = []
const resourceKeyMap = new Map<string, string>()
const reserved = new Set<string>()
for (const resource of manifest.resources) {
const staged = stagedEntries.get(resource.path)
if (!staged?.tempKey) throw new Error(`Resource was not staged: ${resource.path}`)
const restoredValue = await readStagedResource(storage, { resource, tempKey: staged.tempKey })
const targets: ResourceWritePlan['targets'] = []
for (const originalKey of resource.originalStorageKeys) {
const existingValue = await storage.getBlob(originalKey)
let targetKey = originalKey
let needsWrite = existingValue === null
if (existingValue !== null && existingValue !== restoredValue) {
targetKey = await findAvailableCollisionKey(storage, originalKey, reserved)
needsWrite = true
}
if (reserved.has(targetKey)) {
targetKey = await findAvailableCollisionKey(storage, originalKey, reserved)
needsWrite = true
}
reserved.add(targetKey)
resourceKeyMap.set(originalKey, targetKey)
targets.push({ originalKey, targetKey, needsWrite })
}View on GitHub (pinned to 81571269ad)
Solutions
- Ensure validateManifestEntries runs before createResourcePlans (it does in importBackupArchive).
- Confirm isBackupResourcePath classifies every manifest resource path as a resource during the reading phase.
- If the manifest was edited, restore it so it matches the archive.
- Regenerate the backup.
Defensive patterns
Strategy: try-catch
Validate before calling
// Before import, ensure every resource path was staged with a tempKey during reading.
for (const r of manifest.resources) {
const staged = stagedEntries.get(r.path)
if (!staged?.tempKey) throw new Error('Resource not staged: ' + r.path)
} Try / catch
try {
await importBackupArchive(file, options)
} catch (error) {
if (error instanceof Error && error.message.startsWith('Resource was not staged')) {
// Usually means validateManifestEntries was bypassed; re-run it before createResourcePlans.
throw new Error('Resource staging incomplete', { cause: error })
}
throw error
} Prevention
- Always run validateManifestEntries before createResourcePlans.
- Keep isBackupResourcePath classification consistent between the reading switch and manifest resource paths.
- Regenerate backups rather than hand-editing resource entries.
When it happens
Trigger: manifest.resources[i].path is absent from stagedEntries, or its staged entry has tempKey undefined when createResourcePlans runs.
Common situations: Normally caught earlier by validateManifestEntries (error 126). Reachable if validation was skipped, if a resource path was staged via the JSON branch instead of the resource branch due to an isBackupResourcePath mismatch, or if tempKey assignment changed.
Related errors
- Session was not staged: ${descriptor.path}
- Backup manifest entry list is incomplete
- Staged resource is missing: ${plan.resource.path}
- Could not allocate a resource key for: ${originalKey}
- Backup entry is too large: ${entry.path}
AI-assisted analysis of chatboxai/chatbox@81571269ad (2026-08-12).
Data as JSON: /api/errors/5cd0d2551baf50e6.
Report an issue: GitHub.