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
- Produce the data URI with FileReader.readAsDataURL(file) (or canvas.toDataURL) which always yields data:<mime>;base64,<data>.
- If you already have raw base64, wrap it: `data:image/png;base64,${b64}`.
- 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
- Always generate avatar data URIs with FileReader.readAsDataURL or canvas.toDataURL.
- Never pass blob:/object URLs or remote image URLs where inline data is expected.
- Wrap raw base64 as `data:<mime>;base64,${b64}` before sending.
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.