chatboxai/chatbox · error

Session-scoped resource must reference exactly one session

Error message

Session-scoped resource must reference exactly one session: ${resource.id}

What it means

Thrown when a resource has scope 'session' but its sessionIds length is not exactly 1. Session-scoped resources must be bound to one and only one session.

Solutions

  1. Set scope to 'shared' if the resource legitimately belongs to multiple sessions.
  2. Attach exactly one sessionId if it is truly session-scoped.
  3. Re-export with correct scope assignment.

Example fix

// before
// scope 'session' with 0 or 2+ sessionIds

// after
for (const r of manifest.resources) {
  if (r.scope === 'session' && r.sessionIds.length !== 1) {
    r.scope = r.sessionIds.length === 0 ? 'global' : 'shared'
  }
}
Defensive patterns

Strategy: validation

Validate before calling

function sessionScopedResourcesAreValid(manifest: BackupManifest): boolean {
  return manifest.resources.every((r) => r.scope !== 'session' || r.sessionIds.length === 1)
}

Try / catch

try {
  validateBackupManifestGraph(manifest)
} catch (error) {
  if (/Session-scoped resource/.test((error as Error).message)) fixSessionScope(manifest)
  throw error
}

Prevention

When it happens

Trigger: resource.scope === 'session' and resource.sessionIds.length is 0 or >= 2.

Common situations: Scope mislabeled; a shared resource incorrectly marked session-scoped; exporter set scope before finalizing session links.

Related errors


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

Appendix: source

Thrown at src/renderer/packages/backup/types.ts:119

  }
  for (const resource of manifest.resources) {
    if (resourceIds.has(resource.id)) throw new Error(`Duplicate resource id in manifest: ${resource.id}`)
    resourceIds.add(resource.id)
    const ownResourceKeys = new Set<string>()
    for (const key of resource.originalStorageKeys) {
      if (ownResourceKeys.has(key)) throw new Error(`Resource contains a duplicate storage key: ${resource.id}`)
      ownResourceKeys.add(key)
      if (resourceKeys.has(key)) throw new Error(`Duplicate resource storage key in manifest: ${key}`)
      resourceKeys.add(key)
    }
    const ownSessionIds = new Set<string>()
    for (const sessionId of resource.sessionIds) {
      if (ownSessionIds.has(sessionId)) throw new Error(`Resource contains a duplicate session id: ${resource.id}`)
      ownSessionIds.add(sessionId)
      if (!sessionIds.has(sessionId)) throw new Error(`Resource references an unknown session: ${sessionId}`)
    }
    if (resource.scope === 'session' && resource.sessionIds.length !== 1) {
      throw new Error(`Session-scoped resource must reference exactly one session: ${resource.id}`)
    }
    if (resource.scope === 'global' && resource.sessionIds.length !== 0) {
      throw new Error(`Global resource must not reference a session: ${resource.id}`)
    }
  }
  const resourcesById = new Map(manifest.resources.map((resource) => [resource.id, resource]))
  const sessionsById = new Map(manifest.sessions.map((session) => [session.id, session]))
  for (const session of manifest.sessions) {
    const ownResourceIds = new Set<string>()
    for (const resourceId of session.resourceIds) {
      if (ownResourceIds.has(resourceId)) throw new Error(`Session contains a duplicate resource id: ${session.id}`)
      ownResourceIds.add(resourceId)
      if (!resourceIds.has(resourceId)) throw new Error(`Session references an unknown resource: ${resourceId}`)
      if (!resourcesById.get(resourceId)?.sessionIds.includes(session.id)) {
        throw new Error(`Session/resource mapping is inconsistent: ${session.id}/${resourceId}`)
      }
    }
  }

View on GitHub (pinned to 81571269ad)