usememos/memos · error

attachment is missing

Error message

attachment is missing

What it means

ResolveAttachmentS3Driver guards its inputs in order: a nil *Attachment triggers "attachment is missing" before any payload inspection. The function needs a loaded attachment (including its Payload field) to resolve the S3 storage driver for operations like presigned URL generation or blob reads.

Source

Thrown at store/attachment.go:281

func (s *Store) getAttachmentStorageCleanupInstanceSetting(ctx context.Context, attachments []*Attachment) (*storepb.InstanceStorageSetting, error) {
	for _, attachment := range attachments {
		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 {

View on GitHub (pinned to 14d757ce1f)

Solutions

  1. Check the GetAttachment result for nil before resolving the S3 driver
  2. Return a not-found error to the caller at the lookup site instead of proceeding
  3. Add a unit test covering nil attachment input

Example fix

// before
att, _ := store.GetAttachment(ctx, find)
driver, s3obj, err := store.ResolveAttachmentS3Driver(ctx, att)
// after
att, err := store.GetAttachment(ctx, find)
if err != nil {
    return err
}
if att == nil {
    return status.Error(codes.NotFound, "attachment not found")
}
driver, s3obj, err := store.ResolveAttachmentS3Driver(ctx, att)
Defensive patterns

Strategy: type-guard

Validate before calling

if attachment == nil {
    return errors.New("cannot resolve S3 driver: attachment not loaded")
}

Type guard

func hasAttachment(a *store.Attachment) bool { return a != nil }

Prevention

When it happens

Trigger: Calling ResolveAttachmentS3Driver with a nil attachment pointer, typically after a GetAttachment/FindAttachment lookup that returned nil without checking.

Common situations: Handling an attachment ID from a URL that no longer exists and passing the nil result straight to S3 resolution; refactors that moved the nil check out of the caller.

Related errors


AI-assisted analysis of usememos/memos@14d757ce1f (2026-08-15). Data as JSON: /api/errors/a073adf1a52dff92. Report an issue: GitHub.