{"record":{"id":"85919f3d6f90b669","repo":"jesseduffield/lazygit","slug":"expected-a-string-or-a-sequence-of-strings-for-key","errorCode":null,"errorMessage":"expected a string or a sequence of strings for keybinding, got %v","messagePattern":"expected a string or a sequence of strings for keybinding, got (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/config/keybinding.go","lineNumber":34,"sourceCode":"// written in YAML/JSON as either a single scalar string or as a sequence of\n// strings.\ntype Keybinding []string\n\nfunc (k *Keybinding) UnmarshalYAML(node *yaml.Node) error {\n\tvar ss []string\n\tswitch node.Kind {\n\tcase yaml.ScalarNode:\n\t\tvar s string\n\t\tif err := node.Decode(&s); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tss = []string{s}\n\tcase yaml.SequenceNode:\n\t\tif err := node.Decode(&ss); err != nil {\n\t\t\treturn err\n\t\t}\n\tdefault:\n\t\treturn fmt.Errorf(\"expected a string or a sequence of strings for keybinding, got %v\", node.Tag)\n\t}\n\t// Drop empty and <disabled> entries so clients never have to special-case\n\t// them: an empty Keybinding means \"no key bound\", a non-empty one is\n\t// guaranteed to contain only real keys.\n\t*k = lo.Filter(ss, func(s string, _ int) bool {\n\t\treturn s != \"\" && s != \"<disabled>\"\n\t})\n\treturn nil\n}\n\nfunc (k Keybinding) MarshalYAML() (any, error) {\n\tif len(k) == 1 {\n\t\treturn k[0], nil\n\t}\n\t// Render multi-key bindings in flow style (`[a, b]`) rather than the default\n\t// block style, which is more compact and reads better in the generated docs.\n\tnode := &yaml.Node{\n\t\tKind:  yaml.SequenceNode,","sourceCodeStart":16,"sourceCodeEnd":52,"githubUrl":"https://github.com/jesseduffield/lazygit/blob/c477a2959b229fbf3284be0d4d2904ab61ec3c94/pkg/config/keybinding.go#L16-L52","documentation":"Thrown while unmarshalling a user-config keybinding in pkg/config/keybinding.go. The custom Keybinding type accepts either a plain YAML string or a sequence of strings; any other YAML node kind (map, bool, number written unquoted, null) reaches the default branch and is rejected with the offending node's tag. This is lazygit's config parser enforcing that every keybinding normalizes to a []string of real key names.","triggerScenarios":"Writing `quit: 5` or `quit: true` (unquoted scalar decoded as int/bool tag), `quit: {key: q}` (mapping node), or `quit:` with a null value in the YAML user config, then starting lazygit (or running any code path that yaml-decodes into the Keybinding type).","commonSituations":"Users copy-pasting YAML from chat/wiki where quotes got stripped; using a bare number as a key name (e.g. `switchTab: 1` instead of `switchTab: '1'`); indentation mistakes turning a value into a nested map; switching from a string value to a structured form that the schema never supported.","solutions":["Open the user config file and change the offending keybinding to a single quoted string (e.g. `quit: 'q'`) or a YAML list of strings (`quit: [ctrl-q, q]`).","Quote any keybinding that looks like a number, bool, or null (`'1'`, `'true'`, `'~'`).","Check the line/column reported in the accompanying YAML error to find which key triggered the decode.","Restart lazygit to confirm the config parses."],"exampleFix":"# before (user config.yml)\nquit: 5\n\n# after\nquit: '5'","handlingStrategy":"validation","validationCode":"// Before yaml.Unmarshal into the config, assert every keybinding node is a string or sequence:\nfunc assertKeybindingNode(path string, node *yaml.Node) error {\n\tif node.Kind != yaml.ScalarNode && node.Kind != yaml.SequenceNode {\n\t\treturn fmt.Errorf(\"%s: expected string or list of strings, got %v\", path, node.Tag)\n\t}\n\treturn nil\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always quote keybinding values in YAML ('1', 'true') so they decode as strings.","Run lazygit with a linter/CI step that yaml-decodes the config before deploying it to machines.","Keep keybindings as either a plain string or a list of strings — never a map."],"tags":["config","yaml","keybinding"],"backgroundTag":null,"analyzedSha":"c477a2959b229fbf3284be0d4d2904ab61ec3c94","analyzedAt":"2026-08-15T08:34:32.451Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}