{"record":{"id":"e06d235425619fff","repo":"Tencent/WeKnora","slug":"unknown-credential-field","errorCode":null,"errorMessage":"unknown credential field: ","messagePattern":"unknown credential field: ","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/application/service/model.go","lineNumber":339,"sourceCode":"\tif existing.IsBuiltin && !types.IsSystemAdminFromContext(ctx) {\n\t\treturn apperrors.NewForbiddenError(\n\t\t\t\"only system administrators can modify builtin model credentials\")\n\t}\n\n\tchanged := false\n\tswitch field {\n\tcase \"api_key\":\n\t\tif existing.Parameters.APIKey != \"\" {\n\t\t\texisting.Parameters.APIKey = \"\"\n\t\t\tchanged = true\n\t\t}\n\tcase \"app_secret\":\n\t\tif existing.Parameters.AppSecret != \"\" {\n\t\t\texisting.Parameters.AppSecret = \"\"\n\t\t\tchanged = true\n\t\t}\n\tdefault:\n\t\treturn errors.New(\"unknown credential field: \" + field)\n\t}\n\tif !changed {\n\t\treturn nil\n\t}\n\tif existing.IsBuiltin {\n\t\texisting.ManagedBy = \"\"\n\t}\n\tif err := s.repo.Update(ctx, existing); err != nil {\n\t\treturn err\n\t}\n\tlogger.Infof(ctx, \"Model credential cleared by user: id=%s field=%s\", id, field)\n\treturn nil\n}\n\n// DeleteModel removes a model from the repository\nfunc (s *modelService) DeleteModel(ctx context.Context, id string) error {\n\tlogger.Info(ctx, \"Start deleting model\")\n\tlogger.Infof(ctx, \"Deleting model ID: %s\", id)","sourceCodeStart":321,"sourceCodeEnd":357,"githubUrl":"https://github.com/Tencent/WeKnora/blob/988cbb03305e055d8ebb7d46d9ac6cc0803cd074/internal/application/service/model.go#L321-L357","documentation":"ClearModelCredential allows clearing whitelisted credential fields on an existing model; any field name outside the switch's known cases (e.g. api_key, app_secret) hits default and returns errors.New(\"unknown credential field: \" + field). It is a strict allow-list check to prevent silently no-op clearing of arbitrary or misspelled fields.","triggerScenarios":"Calling ClearModelCredential with a field string that is not one of the supported cases — e.g. \"apiKey\" vs \"api_key\", \"secret\", \"password\", or an empty field name from an unbound request parameter.","commonSituations":"Client sends a typo'd or camelCase field name while the service expects snake_case; an API consumer tries to clear a field the library does not manage as a credential; a config-driven cleanup job lists field names that no longer exist after a refactor.","solutions":["Log the exact field value received and correct the caller to use one of the supported snake_case names (e.g. \"api_key\", \"app_secret\").","Verify against the service's switch statement (or API docs) which credential fields are clearable, and update client code/config to match.","At the API boundary, validate field against the allow-list and return a 400 with the list of valid field names.","If a new credential field genuinely needs clearing, extend the switch in ClearModelCredential with a new case rather than passing an unknown name."],"exampleFix":"// before\nclearModelCredential(ctx, modelID, \"apiKey\")\n// after\nclearModelCredential(ctx, modelID, \"api_key\") // supported field name","handlingStrategy":"validation","validationCode":"var validCredentialFields = map[string]bool{\"api_key\": true, \"app_secret\": true}\nif !validCredentialFields[field] {\n    return fmt.Errorf(\"field %q is not a clearable credential\", field)\n}\nerr := svc.ClearModelCredential(ctx, modelID, field)","typeGuard":"func isClearableCredentialField(f string) bool { return f == \"api_key\" || f == \"app_secret\" }","tryCatchPattern":"err := svc.ClearModelCredential(ctx, modelID, field)\nif err != nil {\n    if strings.HasPrefix(err.Error(), \"unknown credential field:\") {\n        return fmt.Errorf(\"%w (valid: api_key, app_secret)\", err)\n    }\n    return err\n}","preventionTips":["Use the exact snake_case field names the service documents.","Centralize credential field names as constants shared by client and service.","Validate field names against the allow-list at the API boundary.","When adding credential fields, extend the service switch and constants together."],"tags":["go","validation","allow-list","credential-management"],"backgroundTag":"invalid-field-name","analyzedSha":"988cbb03305e055d8ebb7d46d9ac6cc0803cd074","analyzedAt":"2026-09-02T14:41:08.344Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}