{"record":{"id":"e13f6a278455dc91","repo":"usememos/memos","slug":"id-must-be-omitted","errorCode":null,"errorMessage":"id must be omitted","messagePattern":"id must be omitted","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"store/deployment_config.go","lineNumber":160,"sourceCode":"\tcontent, err := io.ReadAll(io.LimitReader(file, maxDeploymentConfigurationSize+1))\n\tif err != nil {\n\t\treturn errors.Wrap(err, \"failed to read file\")\n\t}\n\tif len(content) > maxDeploymentConfigurationSize {\n\t\treturn errors.Errorf(\"file exceeds %d bytes\", maxDeploymentConfigurationSize)\n\t}\n\tif err := (protojson.UnmarshalOptions{DiscardUnknown: false}).Unmarshal(content, message); err != nil {\n\t\tif matches := protoJSONUnknownFieldMatcher.FindStringSubmatch(err.Error()); len(matches) == 2 {\n\t\t\treturn errors.Errorf(\"failed to decode protobuf JSON: unknown field %q\", matches[1])\n\t\t}\n\t\treturn errors.New(\"failed to decode protobuf JSON; verify field names, value types, and JSON syntax\")\n\t}\n\treturn nil\n}\n\nfunc validateDeploymentIdentityProvider(provider *storepb.IdentityProvider) error {\n\tif provider.Id != 0 {\n\t\treturn errors.New(\"id must be omitted\")\n\t}\n\tif !base.UIDMatcher.MatchString(provider.Uid) {\n\t\treturn errors.New(\"uid is invalid\")\n\t}\n\tif strings.TrimSpace(provider.Name) == \"\" {\n\t\treturn errors.New(\"name is required\")\n\t}\n\tif provider.Type != storepb.IdentityProvider_OAUTH2 {\n\t\treturn errors.New(\"type must be OAUTH2\")\n\t}\n\tif provider.IdentifierFilter != \"\" {\n\t\tif _, err := regexp.Compile(provider.IdentifierFilter); err != nil {\n\t\t\treturn errors.Wrap(err, \"identifierFilter must be a valid regular expression\")\n\t\t}\n\t}\n\tconfig := provider.Config.GetOauth2Config()\n\tif config == nil {\n\t\treturn errors.New(\"config.oauth2Config is required\")","sourceCodeStart":142,"sourceCodeEnd":178,"githubUrl":"https://github.com/usememos/memos/blob/14d757ce1fb31c78590f374bc042f8dbedbc20d7/store/deployment_config.go#L142-L178","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\n{ \"id\": 3, \"uid\": \"github\", \"name\": \"GitHub\", \"type\": \"OAUTH2\", ... }\n// after\n{ \"uid\": \"github\", \"name\": \"GitHub\", \"type\": \"OAUTH2\", ... }","handlingStrategy":"validation","validationCode":"if provider.Id != 0 {\n    return fmt.Errorf(\"deployment IdP %q must not set id; it is assigned on insert\", provider.Uid)\n}","typeGuard":"func isBootstrapIdP(p *storepb.IdentityProvider) bool {\n    return p != nil && p.Id == 0 && base.UIDMatcher.MatchString(p.Uid)\n}","tryCatchPattern":null,"preventionTips":["Strip server-assigned fields (id) when exporting IdPs into bootstrap files","Keep deployment IdP files minimal: uid, name, type, config"],"tags":["deployment","identity-provider","validation","configuration"],"backgroundTag":null,"analyzedSha":"14d757ce1fb31c78590f374bc042f8dbedbc20d7","analyzedAt":"2026-08-15T09:27:36.538Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}