{"record":{"id":"dc9825575c6c6e09","repo":"usememos/memos","slug":"general-instance-setting-is-required","errorCode":null,"errorMessage":"GENERAL instance setting is required","messagePattern":"GENERAL instance setting is required","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"store/auth_config.go","lineNumber":34,"sourceCode":"var ErrUnsafeAuthenticationConfiguration = errors.New(\"password authentication for regular users cannot be disabled without an effective identity provider\")\n\n// AuthenticationConfigState is the stored authentication configuration read inside a transaction.\ntype AuthenticationConfigState struct {\n\tGeneralSetting    *InstanceSetting\n\tIdentityProviders []*IdentityProvider\n}\n\n// AuthenticationConfigMutation validates and applies one stored authentication mutation atomically.\ntype AuthenticationConfigMutation struct {\n\tUpsertGeneralSetting     *InstanceSetting\n\tDeleteIdentityProviderID *int32\n\tValidate                 func(*AuthenticationConfigState) error\n}\n\n// UpsertInstanceGeneralSettingSafely validates and stores GENERAL as one serialized operation.\nfunc (s *Store) UpsertInstanceGeneralSettingSafely(ctx context.Context, setting *storepb.InstanceSetting) (*storepb.InstanceSetting, error) {\n\tif setting == nil || setting.Key != storepb.InstanceSettingKey_GENERAL || setting.GetGeneralSetting() == nil {\n\t\treturn nil, errors.New(\"GENERAL instance setting is required\")\n\t}\n\tvalue, err := protojson.Marshal(setting.GetGeneralSetting())\n\tif err != nil {\n\t\treturn nil, errors.Wrap(err, \"failed to marshal GENERAL instance setting\")\n\t}\n\traw := &InstanceSetting{Name: storepb.InstanceSettingKey_GENERAL.String(), Value: string(value)}\n\tmutation := &AuthenticationConfigMutation{\n\t\tUpsertGeneralSetting: raw,\n\t\tValidate: func(state *AuthenticationConfigState) error {\n\t\t\treturn s.validateAuthenticationMutationState(state, setting.GetGeneralSetting(), nil)\n\t\t},\n\t}\n\tif err := s.applyAuthenticationConfigMutation(ctx, mutation); err != nil {\n\t\treturn nil, err\n\t}\n\tresult := cloneInstanceSetting(setting)\n\ts.cacheInstanceSetting(ctx, result)\n\treturn result, nil","sourceCodeStart":16,"sourceCodeEnd":52,"githubUrl":"https://github.com/usememos/memos/blob/14d757ce1fb31c78590f374bc042f8dbedbc20d7/store/auth_config.go#L16-L52","documentation":"UpsertInstanceGeneralSettingSafely requires a fully-formed GENERAL instance setting: a non-nil storepb.InstanceSetting whose Key equals InstanceSettingKey_GENERAL and whose general_setting oneof is populated. Any nil argument, wrong key, or missing oneof content yields this error before marshaling or transactional validation begins.","triggerScenarios":"Passing nil; passing a setting with Key set to another InstanceSettingKey; passing a GENERAL-keyed setting whose GetGeneralSetting() is nil.","commonSituations":"Callers building InstanceSetting piecemeal and forgetting the oneof; deserializing a setting from JSON where the general_setting field was absent; copy-paste from another setting's upsert path.","solutions":["Construct the full message: Key: storepb.InstanceSettingKey_GENERAL and GeneralSetting: &storepb.InstanceSetting_GeneralSetting{...}","Nil-check the parsed message's GetGeneralSetting() before upserting","Log the setting key and oneof presence when this validation fails to catch construction bugs"],"exampleFix":"// before\n_, err := s.UpsertInstanceGeneralSettingSafely(ctx, &storepb.InstanceSetting{})\n// after\n_, err := s.UpsertInstanceGeneralSettingSafely(ctx, &storepb.InstanceSetting{\n    Key: storepb.InstanceSettingKey_GENERAL,\n    Value: &storepb.InstanceSetting_GeneralSetting{\n        GeneralSetting: general,\n    },\n})","handlingStrategy":"type-guard","validationCode":"if setting == nil || setting.Key != storepb.InstanceSettingKey_GENERAL || setting.GetGeneralSetting() == nil {\n    return errors.New(\"refusing to upsert malformed GENERAL setting\")\n}","typeGuard":"func isGeneralSetting(s *storepb.InstanceSetting) bool {\n    return s != nil &&\n        s.Key == storepb.InstanceSettingKey_GENERAL &&\n        s.GetGeneralSetting() != nil\n}","tryCatchPattern":null,"preventionTips":["Always populate the oneof (GeneralSetting) when building InstanceSetting","After deserializing settings from JSON, assert the oneof before saving"],"tags":["store","settings","protobuf","validation"],"backgroundTag":null,"analyzedSha":"14d757ce1fb31c78590f374bc042f8dbedbc20d7","analyzedAt":"2026-08-15T09:27:36.538Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}