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

  1. Remove the "id" field (or set it to 0) from the deployment IdP JSON
  2. Adjust export tooling to strip server-assigned fields when emitting bootstrap files
  3. 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

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


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