usememos/memos · error
S3 object key is missing
Error message
S3 object key is missing
What it means
ResolveAttachmentS3Driver throws "S3 object key is missing" when the S3Object payload exists but its Key field is an empty string. Without a key there is no object address in the bucket, so presigning or reading would be meaningless; the function fails fast rather than issuing requests for "".
Source
Thrown at store/attachment.go:291
}
return nil, nil
}
// ResolveAttachmentS3Driver resolves the storage driver referenced by an S3
// attachment payload, validating the payload and supplying the instance setting.
func (s *Store) ResolveAttachmentS3Driver(ctx context.Context, attachment *Attachment) (storage.Driver, *storepb.AttachmentPayload_S3Object, error) {
if attachment == nil {
return nil, nil, errors.New("attachment is missing")
}
if attachment.Payload == nil {
return nil, nil, errors.New("attachment payload is missing")
}
s3Object := attachment.Payload.GetS3Object()
if s3Object == nil {
return nil, nil, errors.New("S3 object payload is missing")
}
if s3Object.Key == "" {
return nil, nil, errors.New("S3 object key is missing")
}
instanceStorageSetting, err := s.GetInstanceStorageSetting(ctx)
if err != nil {
return nil, nil, errors.Wrap(err, "failed to get instance storage setting")
}
driver, err := ResolveStorageDriver(ctx, instanceStorageSetting, s3Object.StorageId, s3Object.S3Config)
if err != nil {
return nil, nil, errors.Wrap(err, "failed to resolve storage driver")
}
return driver, s3Object, nil
}
// AttachmentNeedsInstanceStorageSetting reports whether cleanup should load
// the configured storage registry for an S3 attachment.
func AttachmentNeedsInstanceStorageSetting(attachment *Attachment) bool {
if attachment == nil || attachment.StorageType != storepb.AttachmentStorageType_S3 {
return falseView on GitHub (pinned to 14d757ce1f)
Solutions
- Repair the stored payload so s3_object.key holds the real object key
- Validate the key is non-empty at attachment-create time before persisting
- If the blob is unrecoverable, delete the attachment record or mark it LOCAL-stubbed
Example fix
// before (writing)
payload.S3Object = &storepb.AttachmentPayload_S3Object{BucketId: b, StorageId: s}
// after
payload.S3Object = &storepb.AttachmentPayload_S3Object{Key: objectKey, BucketId: b, StorageId: s} Defensive patterns
Strategy: validation
Validate before calling
if s3 := attachment.Payload.GetS3Object(); s3 == nil || s3.Key == "" {
return errors.New("attachment has no S3 object key")
} Type guard
func validS3Key(s3 *storepb.AttachmentPayload_S3Object) bool {
return s3 != nil && s3.Key != ""
} Prevention
- Validate the object key when writing S3 attachments; never persist empty keys
- Audit backfill scripts to ensure the key field is copied
When it happens
Trigger: Attachment rows whose payload.s3_object was stored with an empty key — usually via custom writes, migrations, or truncated serialization.
Common situations: Hand-crafted backfill scripts that set bucket but not key; payload protojson that dropped the key due to a field-name typo (e.g. "objectKey" vs "key"); deleted S3 objects leaving empty-key placeholders.
Related errors
- attachment is missing
- attachment payload is missing
- S3 object payload is missing
- Internal
- default storage is not configured
AI-assisted analysis of usememos/memos@14d757ce1f (2026-08-15).
Data as JSON: /api/errors/2f33641825df77f3.
Report an issue: GitHub.