hcengineering/platform · error · NetworkError
Network error ${error}
Error message
Network error ${error} What it means
StorageClientImpl.put wraps its raw fetch to uploadUrl in try/catch; any exception thrown by fetch itself (DNS failure, connection refused/reset, TLS error, abort) is rethrown as NetworkError(`Network error ${error}`). Note this wraps only transport-level failures — HTTP error statuses are handled separately.
Source
Thrown at foundations/core/packages/api-client/src/storage/client.ts:115
throw new StorageError('Missing response body')
}
return Readable.from(response.body)
}
async put (objectName: string, stream: Readable | Buffer | string, contentType: string, size?: number): Promise<Blob> {
const buffer = await toBuffer(stream)
const file = new File([new Uint8Array(buffer)], objectName, { type: contentType })
const formData = new FormData()
formData.append('file', file)
let response
try {
response = await fetch(this.uploadUrl, {
method: 'POST',
body: formData,
headers: { ...this.headers }
})
} catch (error: any) {
throw new NetworkError(`Network error ${error}`)
}
if (!response.ok) {
throw new StorageError(await response.text())
}
const result = (await response.json()) as BlobUploadResult[]
if (Object.hasOwn(result[0], 'id')) {
const fileResult = result[0] as BlobUploadSuccess
return {
_class: core.class.Blob,
_id: fileResult.id as Ref<Blob>,
space: core.space.Configuration,
modifiedOn: fileResult.metadata.lastModified,
modifiedBy: core.account.System,
provider: '',
contentType: fileResult.metadata.contentType,
etag: fileResult.metadata.etag,
version: null,
size: fileResult.metadata.sizeView on GitHub (pinned to 63e28dc964)
Solutions
- Verify uploadUrl is reachable: curl -X POST the upload endpoint from the same network.
- Check config.UPLOAD_URL resolution in connectStorage (it must be absolute or a path concatenated with the base URL, with :workspace substituted).
- Inspect the inner error text in NetworkError message (ECONNREFUSED, ENOTFOUND, etc.) and fix infrastructure accordingly.
- Add retry with backoff for transient connection errors around put().
Example fix
// before
const blob = await storage.put(name, stream, contentType)
// after
let blob
for (let attempt = 0; attempt < 3; attempt++) {
try {
blob = await storage.put(name, stream, contentType)
break
} catch (err) {
if (err instanceof NetworkError && attempt < 2) {
await new Promise(r => setTimeout(r, 2 ** attempt * 500))
continue
}
throw err
}
} Defensive patterns
Strategy: retry
Validate before calling
// Validate upload URL before uploading
const u = new URL(uploadUrl)
if (!/^https?:$/.test(u.protocol)) throw new Error(`Bad upload URL: ${uploadUrl}`)
// optionally: await fetch(uploadUrl, { method: 'OPTIONS' }) as a reachability probe Type guard
function isNetworkError(e: unknown): e is NetworkError {
return e instanceof NetworkError
} Try / catch
try {
return await storage.put(name, stream, contentType)
} catch (e) {
if (isNetworkError(e)) {
// transient transport failure — retry with backoff
await sleep(1000)
return storage.put(name, stream, contentType)
}
throw e
} Prevention
- Confirm UPLOAD_URL resolves correctly for the current environment at startup.
- Add retries with exponential backoff around put() for transient network errors.
- Keep uploads under proxy body-size limits; chunk large files.
- Monitor upload service availability with health checks.
When it happens
Trigger: Calling storageClient.put(...) when the upload URL is unreachable: wrong UPLOAD_URL config, upload service down, DNS failure, connection reset mid-upload of large multipart bodies, or TLS certificate problems.
Common situations: UPLOAD_URL not set or pointing at localhost in a container; k8s service name typo; oversized uploads hitting proxy body-size limits that kill the connection; transient network blips between services.
Related errors
- response.statusText
- await response.text()
- Storage error ${error.error}
- Failed to delete file
- Failed to delete file
AI-assisted analysis of hcengineering/platform@63e28dc964 (2026-08-29).
Data as JSON: /api/errors/9bee560bff3d5d19.
Report an issue: GitHub.