hcengineering/platform · error
no object found
Error message
no object found
What it means
stat looks up an object's metadata in S3. This log fires when the S3 HeadObject call fails with an unexpected (non-404) status — i.e. the lookup failed for a reason other than 'object absent' — and the underlying error is rethrown. Note the 404 case passes through silently; any other failure logs 'no object found' with the real error.
Source
Thrown at foundations/server/packages/s3/src/index.ts:327
Bucket: this.getBucketId(wsIds),
Key: this.getDocumentKey(wsIds, objectName)
})
const rootPrefix = this.rootPrefix(wsIds)
return {
provider: '',
_class: core.class.Blob,
_id: this.stripPrefix(rootPrefix, objectName) as Ref<Blob>,
contentType: result.ContentType ?? '',
size: result.ContentLength ?? 0,
etag: result.ETag ?? '',
space: core.space.Configuration,
modifiedBy: core.account.System,
modifiedOn: result.LastModified?.getTime() ?? 0,
version: result.VersionId ?? null
}
} catch (err: any) {
if (err?.$metadata?.httpStatusCode !== 404) {
ctx.warn('no object found', { error: err, objectName, wsIds })
throw err
}
}
}
@withContext('get')
async get (ctx: MeasureContext, wsIds: WorkspaceIds, objectName: string): Promise<Readable> {
return await this.doGet(ctx, wsIds, objectName)
}
async doGet (ctx: MeasureContext, wsIds: WorkspaceIds, objectName: string, range?: string): Promise<Readable> {
try {
const res = await this.client.getObject({
Bucket: this.getBucketId(wsIds),
Key: this.getDocumentKey(wsIds, objectName),
Range: range
})
View on GitHub (pinned to 63e28dc964)
Solutions
- Inspect the logged inner error's $metadata.httpStatusCode and message
- Fix AWS credentials/bucket policy so s3:HeadObject is allowed
- Verify bucket name, region and endpoint configuration
- Retry on transient network/5xx errors
Example fix
// before
const meta = await storage.stat(ctx, objectName, wsIds) // throws on 403
// after
try {
const meta = await storage.stat(ctx, objectName, wsIds)
} catch (err: any) {
if (err?.$metadata?.httpStatusCode === 404) return null // truly absent
throw err
} Defensive patterns
Strategy: try-catch
Validate before calling
if (!process.env.AWS_ACCESS_KEY_ID || !process.env.AWS_REGION) {
throw new Error('S3 credentials/region not configured')
} Type guard
function isNotFound(err: any): boolean {
return err?.$metadata?.httpStatusCode === 404 || err?.name === 'NotFound'
} Try / catch
try {
meta = await storage.stat(ctx, objectName, wsIds)
} catch (err: any) {
if (isNotFound(err)) {
meta = null // genuinely absent
} else if (isRetryable(err)) {
await retry(() => storage.stat(ctx, objectName, wsIds))
} else {
throw err
}
} Prevention
- Pre-check IAM policy allows s3:HeadObject on the bucket
- Verify bucket/region/endpoint config at service startup
- Distinguish 404 from other errors — only 404 means 'absent'
- Add retries with backoff for 5xx/network errors
When it happens
Trigger: Calling stat (directly or via saveFileToS3) when S3 returns errors such as 403 access denied, network/timeout failures, or missing bucket — anything where $metadata.httpStatusCode is not 404.
Common situations: Misconfigured AWS credentials or bucket policy revoking s3:GetObject; wrong region/endpoint config; S3 outages or throttling; VPC/network issues blocking the S3 endpoint.
Related errors
- "npm view" returned error code ${npmVersionSpawnResult.statu
- Unable to resolve version ${version} of package ${name}: ${e
- response.statusText
- Message id is required
- "npm view" returned error code ${npmVersionSpawnResult.statu
AI-assisted analysis of hcengineering/platform@63e28dc964 (2026-08-29).
Data as JSON: /api/errors/b791041c189589c6.
Report an issue: GitHub.