usememos/memos · error
id must be omitted
Error message
id must be omitted
What it means
validateDeploymentIdentityProvider rejects bootstrap IdP configs whose id field is set to anything other than 0. Deployment-provided identity providers are assigned server-side IDs on first insert; an explicit id in the file would collide with or shadow database-assigned IDs, so it must be omitted in the JSON.
Source
Thrown at store/deployment_config.go:160
content, err := io.ReadAll(io.LimitReader(file, maxDeploymentConfigurationSize+1))
if err != nil {
return errors.Wrap(err, "failed to read file")
}
if len(content) > maxDeploymentConfigurationSize {
return errors.Errorf("file exceeds %d bytes", maxDeploymentConfigurationSize)
}
if err := (protojson.UnmarshalOptions{DiscardUnknown: false}).Unmarshal(content, message); err != nil {
if matches := protoJSONUnknownFieldMatcher.FindStringSubmatch(err.Error()); len(matches) == 2 {
return errors.Errorf("failed to decode protobuf JSON: unknown field %q", matches[1])
}
return errors.New("failed to decode protobuf JSON; verify field names, value types, and JSON syntax")
}
return nil
}
func validateDeploymentIdentityProvider(provider *storepb.IdentityProvider) error {
if provider.Id != 0 {
return errors.New("id must be omitted")
}
if !base.UIDMatcher.MatchString(provider.Uid) {
return errors.New("uid is invalid")
}
if strings.TrimSpace(provider.Name) == "" {
return errors.New("name is required")
}
if provider.Type != storepb.IdentityProvider_OAUTH2 {
return errors.New("type must be OAUTH2")
}
if provider.IdentifierFilter != "" {
if _, err := regexp.Compile(provider.IdentifierFilter); err != nil {
return errors.Wrap(err, "identifierFilter must be a valid regular expression")
}
}
config := provider.Config.GetOauth2Config()
if config == nil {
return errors.New("config.oauth2Config is required")View on GitHub (pinned to 14d757ce1f)
Solutions
- Remove the "id" field (or set it to 0) from the deployment IdP JSON
- Adjust export tooling to strip server-assigned fields when emitting bootstrap files
- Keep bootstrap files minimal: uid, name, type, config only
Example fix
// before
{ "id": 3, "uid": "github", "name": "GitHub", "type": "OAUTH2", ... }
// after
{ "uid": "github", "name": "GitHub", "type": "OAUTH2", ... } Defensive patterns
Strategy: validation
Validate before calling
if provider.Id != 0 {
return fmt.Errorf("deployment IdP %q must not set id; it is assigned on insert", provider.Uid)
} Type guard
func isBootstrapIdP(p *storepb.IdentityProvider) bool {
return p != nil && p.Id == 0 && base.UIDMatcher.MatchString(p.Uid)
} Prevention
- Strip server-assigned fields (id) when exporting IdPs into bootstrap files
- Keep deployment IdP files minimal: uid, name, type, config
When it happens
Trigger: A memos-idp-*.json containing "id": 42 (or a non-zero value) — often produced by exporting an existing IdP from the UI/database and reusing it as a bootstrap file.
Common situations: Round-tripping DB rows into deployment files; copy-paste between environments where IDs were recorded; generators that serialize the full proto message including populated IDs.
Related errors
- failed to decode protobuf JSON; verify field names, value ty
- uid is invalid
- name is required
- type must be OAUTH2
- config.oauth2Config is required
AI-assisted analysis of usememos/memos@14d757ce1f (2026-08-15).
Data as JSON: /api/errors/e13f6a278455dc91.
Report an issue: GitHub.