chatboxai/chatbox · warning · Error

Managed resource is missing from blob storage

Error message

Managed resource is missing from blob storage

What it means

Thrown in the export resource loop when storage.getBlob(storageKey) returns null for a key that a session or global settings referenced. The reference was collected via collectSessionResourceReferences/collectGlobalResourceReferences, so the exporter expects a blob to exist; absence means an orphaned reference. Caught in the same loop (lines 352-359) and downgraded to a 'resource-read-failed' warning, so export proceeds without that resource.

Source

Thrown at src/renderer/packages/backup/export-backup.ts:301

          })
        }
      }
      options.onProgress?.({ phase: 'sessions', current: sessionIds.length, total: sessionIds.length })
    }

    const resourceCandidateEntries = Array.from(resourceCandidates.entries())
    for (let index = 0; index < resourceCandidateEntries.length; index++) {
      throwIfAborted(options.signal)
      const [storageKey, candidate] = resourceCandidateEntries[index]
      options.onProgress?.({
        phase: 'resources',
        current: index,
        total: resourceCandidateEntries.length,
        label: candidate.references.find((reference) => reference.filename)?.filename,
      })
      try {
        const storedValue = await options.storage.getBlob(storageKey)
        if (storedValue === null) throw new Error('Managed resource is missing from blob storage')
        const firstReference = candidate.references[0]
        const encoded = encodeStoredBlob(storedValue, firstReference)
        if (encoded.bytes.length > MAX_BACKUP_RESOURCE_ENTRY_BYTES) {
          throw new Error('Managed resource exceeds the backup size limit')
        }
        const checksum = await sha256Checksum(encoded.bytes)
        successfullyReadResourceKeys++
        const dedupeKey = `${checksum.value}:${encoded.encoding}:${encoded.mimeType}`
        const existingResource = deduplicatedResources.get(dedupeKey)
        const sessionIds = unique(
          candidate.references.flatMap((reference) => (reference.sessionId ? [reference.sessionId] : []))
        )
        if (existingResource) {
          existingResource.originalStorageKeys.push(storageKey)
          existingResource.sessionIds = unique([...existingResource.sessionIds, ...sessionIds])
          const candidateScope = resolveResourceScope(candidate)
          if (
            existingResource.scope !== candidateScope ||

View on GitHub (pinned to 81571269ad)

Solutions

  1. Run a referential-integrity sweep that removes or ignores references whose blobs are missing before exporting.
  2. If using external file storage, configure collectSessionResourceReferences to skip external resources (producing an 'external-resource-skipped' warning) instead of treating them as managed blobs.
  3. Re-import or re-attach the missing blobs into managed storage.
  4. Exclude the conversations containing the orphaned references from exportItems.

Example fix

// before: missing blobs warn on every export
await exportBackupArchive(options)
// after: drop references to blobs that no longer exist
for (const key of await storage.getAllKeys()) {
  if (!key.startsWith('picture:') && !key.startsWith('file:')) continue
  if ((await storage.getBlob(key)) === null) {
    // strip the reference from owning sessions/settings before export
  }
}
await exportBackupArchive(options)
Defensive patterns

Strategy: validation

Validate before calling

// Before export, confirm every referenced blob actually exists.
const referenced = collectAllResourceReferences(storage, settings, copilots, sessions)
const missing: string[] = []
for (const key of referenced) {
  if ((await storage.getBlob(key)) === null) missing.push(key)
}
if (missing.length) console.warn('Orphaned resource refs:', missing)

Type guard

// True when the blob backing a reference is present and non-null.
const blobIsPresent = async (storage: BackupStorage, key: string): Promise<boolean> =>
  (await storage.getBlob(key)) !== null

Prevention

When it happens

Trigger: A picture:/file:/link:/parseFile-/parseUrl- storage key is referenced by a message, attachment, avatar, background, or settings field, but getBlob returns null for it during the resource collection phase.

Common situations: A resource was deleted without cleaning up message references; external-file mode where the blob lives outside managed storage; partial cleanup after a failed import; storage backend lost blobs due to quota eviction or an IndexedDB clear.

Related errors


AI-assisted analysis of chatboxai/chatbox@81571269ad (2026-08-12). Data as JSON: /api/errors/abfdd55acdd3e66c. Report an issue: GitHub.