hcengineering/platform · error · PlatformError
Low level storage is not available
Error message
Low level storage is not available
What it means
BackupClient.getOps lazily creates a BackupClientOps wrapper around pipeline.context.lowLevelStorage. If the pipeline context has no lowLevelStorage (undefined), backup/restore operations cannot talk to the underlying storage, so a PlatformError(unknownError(...)) is thrown.
Source
Thrown at foundations/server/packages/server/src/client.ts:355
}
const bevent = createBroadcastEvent(Array.from(classes))
void socket.send(
ctx,
{
result: [bevent]
},
this.binaryMode,
this.useCompression
)
} else {
void socket.send(ctx, { result: tx }, this.binaryMode, this.useCompression)
}
}
getOps (pipeline: Pipeline): BackupClientOps {
if (this.ops === undefined || this.opsPipeline !== pipeline) {
if (pipeline.context.lowLevelStorage === undefined) {
throw new PlatformError(unknownError('Low level storage is not available'))
}
this.ops = new BackupClientOps(pipeline.context.lowLevelStorage)
this.opsPipeline = pipeline
}
return this.ops
}
async loadChunk (ctx: ClientSessionCtx, domain: Domain, idx?: number): Promise<void> {
this.lastRequest = Date.now()
try {
const result = await this.getOps(ctx.pipeline).loadChunk(ctx.ctx, domain, idx)
await ctx.sendResponse(ctx.requestId, result)
} catch (err: any) {
await ctx.sendError(ctx.requestId, 'Failed to upload', unknownError(err))
ctx.ctx.error('failed to loadChunk', { domain, err })
}
}
View on GitHub (pinned to 63e28dc964)
Solutions
- Ensure the pipeline context is initialized with a lowLevelStorage before using BackupClient
- Fix the storage configuration so createStorageFromConfig produces an adapter and it is assigned to context.lowLevelStorage
- Guard backup entry points to check context.lowLevelStorage first and fail with a clear config error
Example fix
// before
client.upload(pipeline, data)
// after
if (pipeline.context.lowLevelStorage === undefined) {
throw new Error('Backup unavailable: storage not configured for this pipeline')
}
client.upload(pipeline, data) Defensive patterns
Strategy: validation
Validate before calling
function assertBackupReady(pipeline) {
if (pipeline?.context?.lowLevelStorage === undefined) {
throw new Error('Backup requires a pipeline initialized with a lowLevelStorage adapter')
}
} Type guard
function hasLowLevelStorage(pipeline) {
return pipeline != null && pipeline.context != null &&
pipeline.context.lowLevelStorage !== undefined
} Try / catch
import { PlatformError } from '@hcengineering/platform'
try {
await backupClient.upload(pipeline, data)
} catch (e) {
if (e instanceof PlatformError && e.message.includes('Low level storage is not available')) {
throw new Error('Storage misconfigured: pipeline has no lowLevelStorage; fix storage config before backup')
}
throw e
} Prevention
- Assert pipeline.context.lowLevelStorage in backup entry points and tests
- Initialize storage adapters during pipeline boot and fail startup if missing
- Cover backup flows with an integration test that requires a bound storage
When it happens
Trigger: Invoking backup operations (via result, closeChunk, upload or clean paths) on a pipeline whose context was built without a lowLevelStorage adapter — e.g. storage not initialized or the pipeline was created before storage adapters were attached.
Common situations: Running backup tooling against a workspace/pipeline that lacks storage binding; server started with storage misconfigured so lowLevelStorage never got assigned; calling backup API before pipeline initialization completes.
Related errors
- Low level storage is not available
- ${infoFile} should present to check
- ${infoFile} should present to restore
- backup.json.gz should present to restore
- Cannot create message, group not found: cardId = ${event.car
AI-assisted analysis of hcengineering/platform@63e28dc964 (2026-08-29).
Data as JSON: /api/errors/3de046faed57708b.
Report an issue: GitHub.