usememos/memos · error

InvalidArgument

InvalidArgument

Error message

invalid data URI format

What it means

extractImageInfo parses avatar data URIs with the regex ^data:(?P<type>.+);base64,(?P<base64>.+). It returns this error when the string does not contain the ';base64,' separator structure — e.g. URL-encoded images, plain base64 without the data: prefix, or data URIs with non-base64 encodings. The regex is anchored, so leading/trailing characters also fail. Surfaced as InvalidArgument.

Source

Thrown at server/router/api/v1/user_service_converters.go:77

	}
}

func convertUserRoleToStore(role v1pb.User_Role) store.Role {
	switch role {
	case v1pb.User_ADMIN:
		return store.RoleAdmin
	default:
		return store.RoleUser
	}
}

// extractImageInfo extracts image type and base64 data from a data URI.
// Data URI format: data:image/png;base64,iVBORw0KGgo...
func extractImageInfo(dataURI string) (string, string, error) {
	dataURIRegex := regexp.MustCompile(`^data:(?P<type>.+);base64,(?P<base64>.+)`)
	matches := dataURIRegex.FindStringSubmatch(dataURI)
	if len(matches) != 3 {
		return "", "", errors.New("invalid data URI format")
	}
	imageType := matches[1]
	base64Data := matches[2]
	return imageType, base64Data, nil
}

// convertSettingKeyToStore converts API setting key to store enum.
func convertSettingKeyToStore(key string) (storepb.UserSetting_Key, error) {
	switch key {
	case v1pb.UserSetting_Key_name[int32(v1pb.UserSetting_GENERAL)]:
		return storepb.UserSetting_GENERAL, nil
	case v1pb.UserSetting_Key_name[int32(v1pb.UserSetting_WEBHOOKS)]:
		return storepb.UserSetting_WEBHOOKS, nil
	case v1pb.UserSetting_Key_name[int32(v1pb.UserSetting_TAGS)]:
		return storepb.UserSetting_TAGS, nil
	default:
		return storepb.UserSetting_KEY_UNSPECIFIED, errors.Errorf("unknown setting key: %s", key)
	}

View on GitHub (pinned to 14d757ce1f)

Solutions

  1. Produce the data URI with FileReader.readAsDataURL(file) (or canvas.toDataURL) which always yields data:<mime>;base64,<data>.
  2. If you already have raw base64, wrap it: `data:image/png;base64,${b64}`.
  3. Ensure the mime type is present and the payload non-empty before sending.

Example fix

// before
avatar = rawBase64String; // 'iVBORw0KGgo...'

// after
avatar = `data:image/png;base64,${rawBase64String}`;
// or from a File: const avatar = await fileToDataUrl(file);
Defensive patterns

Strategy: type-guard

Validate before calling

const DATA_URI_RE = /^data:[^;]+;base64,.+$/;
if (!DATA_URI_RE.test(avatar)) throw new Error('Avatar must be a data:<type>;base64,<data> URI');

Type guard

function isBase64DataUri(v) {
  return typeof v === 'string' && /^data:[^;]+;base64,[A-Za-z0-9+/=]+$/.test(v);
}

Prevention

When it happens

Trigger: UpdateUser avatar set to 'data:image/png' (truncated), raw 'iVBORw0KGgo...' without the data URI wrapper, 'data:image/webp,url=...' style URIs, or a URI where the base64 payload is empty.

Common situations: Frontend using blob: or object URLs instead of reading the File as a data URL via FileReader; third-party avatar URLs passed instead of inline data; size-limited proxies truncating the header.

Related errors


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