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

  1. Inspect the logged inner error's $metadata.httpStatusCode and message
  2. Fix AWS credentials/bucket policy so s3:HeadObject is allowed
  3. Verify bucket name, region and endpoint configuration
  4. 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

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


AI-assisted analysis of hcengineering/platform@63e28dc964 (2026-08-29). Data as JSON: /api/errors/b791041c189589c6. Report an issue: GitHub.