usememos/memos · error
attachment payload is missing
Error message
attachment payload is missing
What it means
ResolveAttachmentS3Driver throws "attachment payload is missing" when the attachment exists but attachment.Payload is nil. Attachments created via legacy code paths or partially populated queries can lack the protobuf payload that identifies where the blob actually lives, so the storage driver cannot be resolved.
Source
Thrown at store/attachment.go:284
if AttachmentNeedsInstanceStorageSetting(attachment) {
instanceStorageSetting, err := s.GetInstanceStorageSetting(ctx)
if err != nil {
return nil, errors.Wrap(err, "failed to get instance storage setting")
}
return instanceStorageSetting, nil
}
}
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, nilView on GitHub (pinned to 14d757ce1f)
Solutions
- Load the attachment through the normal store finder so the payload column is included
- If the row genuinely has no payload, migrate or backfill payload data before using S3 features
- Ensure test fixtures set Payload with a valid S3Object
Example fix
// before
att := &store.Attachment{ID: id, StorageType: storepb.AttachmentStorageType_S3}
driver, obj, err := store.ResolveAttachmentS3Driver(ctx, att)
// after
att, err := store.GetAttachment(ctx, &store.FindAttachment{ID: &id}) // payload populated
driver, obj, err := store.ResolveAttachmentS3Driver(ctx, att) Defensive patterns
Strategy: type-guard
Validate before calling
if attachment == nil || attachment.Payload == nil {
return errors.New("attachment payload unavailable")
} Type guard
func hasPayload(a *store.Attachment) bool {
return a != nil && a.Payload != nil
} Prevention
- Load attachments via store finders that include the payload column
- Keep test fixtures and migrations consistent so payload is always written
When it happens
Trigger: Passing an attachment struct loaded without its payload column, or a hand-constructed Attachment{ID: ...} value with only scalar fields set.
Common situations: Rows written before the payload column existed (schema migration gaps); queries that select a subset of columns; test fixtures that omit Payload.
Related errors
- attachment is missing
- S3 object payload is missing
- S3 object key is missing
- Internal
- default storage is not configured
AI-assisted analysis of usememos/memos@14d757ce1f (2026-08-15).
Data as JSON: /api/errors/c80ec5d890e20ae4.
Report an issue: GitHub.