{"record":{"id":"b5c9a800473cee63","repo":"t8y2/dbx","slug":"key-is-required-b5c9a8","errorCode":null,"errorMessage":"Key is required","messagePattern":"Key is required","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"agents/drivers/etcd2-go/kv.go","lineNumber":407,"sourceCode":"\treturn \"\\x00\"\n}\n\nfunc keyBytesParam(params map[string]json.RawMessage) (string, error) {\n\tif encoded := rawObject(params, \"keyBytes\"); encoded != nil {\n\t\tvalue, err := parseValueObject(encoded)\n\t\tif err != nil {\n\t\t\treturn \"\", err\n\t\t}\n\t\treturn value, nil\n\t}\n\tif raw, ok := params[\"key\"]; ok && raw != nil && string(raw) != \"null\" {\n\t\tvar key string\n\t\tif err := json.Unmarshal(raw, &key); err != nil {\n\t\t\treturn \"\", err\n\t\t}\n\t\treturn key, nil\n\t}\n\treturn \"\", errors.New(\"Key is required\")\n}\n\nfunc rawObject(params map[string]json.RawMessage, key string) map[string]json.RawMessage {\n\traw := params[key]\n\tif len(raw) == 0 || string(raw) == \"null\" {\n\t\treturn nil\n\t}\n\tvar object map[string]json.RawMessage\n\tif err := json.Unmarshal(raw, &object); err != nil || object == nil {\n\t\treturn nil\n\t}\n\treturn object\n}\n\nfunc bytesObject(bytes []byte) map[string]any {\n\treturn map[string]any{\n\t\t\"encoding\": \"base64\",\n\t\t\"data\":     base64.StdEncoding.EncodeToString(bytes),","sourceCodeStart":389,"sourceCodeEnd":425,"githubUrl":"https://github.com/t8y2/dbx/blob/c0390bff16418b651f4728520d99adf8ce48829a/agents/drivers/etcd2-go/kv.go#L389-L425","documentation":"keyBytesParam extracts the key from the params map, accepting either keyBytes (an encoded value object) or key (a JSON string). If neither is present — or key is explicitly null — the driver returns this error before any etcd call. Nearly every key operation (get, put, delete, rename, watch, auth roles) funnels through it.","triggerScenarios":"Calling get/put/delete/rename/watchStart/authRolePermission without a key or keyBytes param, or passing key: null / key as a non-string JSON value that fails to unmarshal into a string.","commonSituations":"Building params dynamically and dropping the key field on an empty variable; sending key as a number or object instead of a string; a UI binding that left the key input empty; copying a params template that uses a different field name.","solutions":["Include a non-null string key in the params, e.g. {\"key\":\"cfg/foo\"}.","Alternatively pass keyBytes for binary keys using the driver's value-object encoding.","Validate the key at the call site (non-empty string) before dispatching the operation.","Check for typos in the param name — it must be exactly \"key\" or \"keyBytes\"."],"exampleFix":"// before\nparams := map[string]any{\"value\": \"x\"} // key missing\nres, err := agent.Handle(ctx, \"put\", params)\n// after\nif k, ok := params[\"key\"].(string); !ok || k == \"\" {\n    return errors.New(\"key must be a non-empty string\")\n}\nres, err := agent.Handle(ctx, \"put\", params)","handlingStrategy":"validation","validationCode":"func requireKey(params map[string]any) (string, error) {\n    k, ok := params[\"key\"].(string)\n    if !ok || k == \"\" {\n        return \"\", errors.New(\"key must be a non-empty string\")\n    }\n    return k, nil\n}","typeGuard":null,"tryCatchPattern":"if _, err := agent.Handle(ctx, \"get\", params); err != nil && strings.Contains(err.Error(), \"Key is required\") {\n    // params lack key/keyBytes; fix construction and re-dispatch\n}","preventionTips":["Validate that key (or keyBytes) is present and non-empty before any key operation","Ensure key is serialized as a JSON string, not a number or object","Use a typed request builder so key can never be dropped","For binary keys, pass keyBytes with the proper value-object encoding"],"tags":["etcd","validation","missing-parameter","key"],"backgroundTag":"missing-required-parameter","analyzedSha":"c0390bff16418b651f4728520d99adf8ce48829a","analyzedAt":"2026-09-05T23:05:10.900Z","contentChangedAt":"2026-09-05T23:05:10.900Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}