{"record":{"id":"7896b79531934067","repo":"usememos/memos","slug":"type-must-be-oauth2","errorCode":null,"errorMessage":"type must be OAUTH2","messagePattern":"type must be OAUTH2","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"store/deployment_config.go","lineNumber":169,"sourceCode":"\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\")\n\t}\n\trequired := []struct {\n\t\tname  string\n\t\tvalue string\n\t}{\n\t\t{name: \"clientId\", value: config.ClientId},\n\t\t{name: \"clientSecret\", value: config.ClientSecret},\n\t\t{name: \"authUrl\", value: config.AuthUrl},\n\t\t{name: \"tokenUrl\", value: config.TokenUrl},","sourceCodeStart":151,"sourceCodeEnd":187,"githubUrl":"https://github.com/usememos/memos/blob/14d757ce1fb31c78590f374bc042f8dbedbc20d7/store/deployment_config.go#L151-L187","documentation":"Thrown when an identity-provider deployment file declares a type other than OAUTH2. The deployment-config path only supports OAuth2 identity providers; the storepb.IdentityProvider proto has other type values (TYPE_UNSPECIFIED, LDAP in some forks) but the file loader rejects anything except \"OAUTH2\" so unsupported providers cannot be silently dropped. Startup of configuration loading fails with this error.","triggerScenarios":"A memos-idp-*.json with \"type\": \"TYPE_UNSPECIFIED\", a missing \"type\" key (defaults to 0 = unspecified), or an LDAP-style provider definition.","commonSituations":"Omitting the type field assuming it is inferred from the config shape; copying a provider definition from older docs or another Memos fork that supported LDAP; protojson enum written with the wrong value name.","solutions":["Set \"type\": \"OAUTH2\" explicitly in the memos-idp-*.json file.","For non-OAuth2 providers, create them at runtime through the admin UI / IdentityProviderService API instead of deployment files."],"exampleFix":"// before\n{ \"uid\": \"github\", \"name\": \"GitHub\", \"config\": { \"oauth2Config\": { ... } } }\n\n// after\n{ \"uid\": \"github\", \"name\": \"GitHub\", \"type\": \"OAUTH2\", \"config\": { \"oauth2Config\": { ... } } }","handlingStrategy":"validation","validationCode":"if provider.Type != storepb.IdentityProvider_OAUTH2 {\n    return errors.New(\"deployment IdP files only support type OAUTH2\")\n}","typeGuard":"func isSupportedIdpType(t storepb.IdentityProvider_Type) bool {\n    return t == storepb.IdentityProvider_OAUTH2\n}","tryCatchPattern":null,"preventionTips":["Always write \"type\": \"OAUTH2\" explicitly in IdP files; never rely on a default.","Create non-OAuth2 providers at runtime via the admin API, not via files."],"tags":["configuration","validation","identity-provider","startup"],"backgroundTag":null,"analyzedSha":"14d757ce1fb31c78590f374bc042f8dbedbc20d7","analyzedAt":"2026-08-15T09:27:36.538Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}