{"record":{"id":"c578fd98b1c0900e","repo":"semaphoreui/semaphore","slug":"invalid-key-format","errorCode":null,"errorMessage":"invalid key format","messagePattern":"invalid key format","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"db/Option.go","lineNumber":20,"sourceCode":"\nimport (\n\t\"fmt\"\n\t\"regexp\"\n)\n\ntype Option struct {\n\tKey   string `db:\"key\" json:\"key\"`\n\tValue string `db:\"value\" json:\"value\"`\n}\n\nfunc ValidateOptionKey(key string) error {\n\tm, err := regexp.Match(`^[\\w.]+$`, []byte(key))\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tif !m {\n\t\treturn fmt.Errorf(\"invalid key format\")\n\t}\n\n\treturn nil\n}\n","sourceCodeStart":2,"sourceCodeEnd":25,"githubUrl":"https://github.com/semaphoreui/semaphore/blob/1774ccb71a0a8b82eb74ea24c23ac9ab713de2fa/db/Option.go#L2-L25","documentation":"ValidateOptionKey checks that an option key matches the regex ^[\\w.]+$ (only word characters and dots). Keys with spaces, slashes, dashes, or empty strings are rejected with 'invalid key format'. It is invoked by GetOptions, DeleteOption, and DeleteOptions before touching the options store.","triggerScenarios":"Calling db.GetOptions, DeleteOption, or DeleteOptions with keys like 'apps/myapp', 'my-app', '' (empty), or containing spaces/special characters.","commonSituations":"Building option keys by concatenating IDs that contain slashes or hyphens (e.g. 'apps.' + a UUID with dashes is fine, but a path-like id is not); user-supplied keys passed through unvalidated; empty key after string formatting.","solutions":["Sanitize the key to only [A-Za-z0-9_.] characters before calling the option APIs","Replace disallowed characters such as '/' and '-' with '.' or '_' when composing keys","Call ValidateOptionKey yourself (or apply the same regex) on user input before persisting it as a key"],"exampleFix":"// before\nopts, err := db.GetOptions(tx, []string{\"apps/\" + appID})\n// after\nkey := strings.ReplaceAll(\"apps.\"+appID, \"/\", \"_\")\nopts, err := db.GetOptions(tx, []string{key})","handlingStrategy":"validation","validationCode":"var keyRe = regexp.MustCompile(`^[\\w.]+$`)\nfunc validOptionKey(k string) bool { return keyRe.MatchString(k) }","typeGuard":null,"tryCatchPattern":"if err := db.ValidateOptionKey(key); err != nil {\n    return fmt.Errorf(\"option key %q rejected: %w\", key, err)\n}\n// then proceed with GetOptions/DeleteOption","preventionTips":["Sanitize keys to [A-Za-z0-9_.] before composing them from IDs","Replace '/' and '-' with '.' or '_' in derived keys","Never pass user input directly as an option key without validation"],"tags":["database","options","validation"],"backgroundTag":"invalid-argument-format","analyzedSha":"1774ccb71a0a8b82eb74ea24c23ac9ab713de2fa","analyzedAt":"2026-09-07T11:00:33.293Z","contentChangedAt":"2026-09-07T11:00:33.293Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}