{"record":{"id":"56ebe5a791da64b1","repo":"charmbracelet/crush","slug":"s-56ebe5","errorCode":null,"errorMessage":"%s","messagePattern":"%s","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/shellconfig/register.go","lineNumber":34,"sourceCode":"\t\"io\"\n\n\t\"github.com/charmbracelet/crush/internal/shell\"\n)\n\nfunc init() {\n\tshell.RegisterBuiltin(\"provider\", handleProvider)\n\tshell.RegisterBuiltin(\"model\", handleModel)\n\tshell.RegisterBuiltin(\"mcp\", handleMCP)\n\tshell.RegisterBuiltin(\"lsp\", handleLSP)\n\tshell.RegisterBuiltin(\"permissions\", handlePermissions)\n\tshell.RegisterBuiltin(\"hook\", handleHook)\n\tshell.RegisterBuiltin(\"option\", handleOption)\n}\n\n// usage prints a usage message to stderr and returns an error.\nfunc usage(stderr io.Writer, msg string) error {\n\tfmt.Fprintln(stderr, msg)\n\treturn fmt.Errorf(\"%s\", msg)\n}\n\n// appendArr appends value to the string slice stored at m[key], creating it if\n// needed, and returns the result.\nfunc appendArr(m map[string]any, key, value string) []any {\n\tarr, _ := m[key].([]any)\n\treturn append(arr, value)\n}\n","sourceCodeStart":16,"sourceCodeEnd":43,"githubUrl":"https://github.com/charmbracelet/crush/blob/7944b8e52225d8805e31eacbf7ef24856b0dfb7a/internal/shellconfig/register.go#L16-L43","documentation":"usage() is the shared helper in internal/shellconfig that prints a usage message to stderr and returns it as an error. Every crushrc builtin handler (applyFlags, handleHook, hookAdd, hookRemove, handleLSP, lspAdd) calls it when arguments are malformed, so this error means one of the shell builtins (provider, model, mcp, lsp, permissions, hook, option) was invoked with the wrong arguments while evaluating a crushrc config file. The message text is the usage string itself, so the error text doubles as documentation.","triggerScenarios":"Calling a builtin in a .crushrc/.crush.json shell config with missing, extra, or invalid arguments — e.g. 'lsp' without a subcommand (lspAdd), 'hook' with an unknown subcommand (handleHook), 'hook add' with fewer than 2 args (hookAdd), 'hook remove' with missing id (hookRemove), or 'provider'/'model' flags applied with wrong values (applyFlags).","commonSituations":"Hand-edited crushrc files with typos or omitted arguments; copying an example config that uses an older builtin syntax after a version change; using crushrc builtins outside their expected form (e.g. 'lsp add' with a missing language server path).","solutions":["Read the usage message printed to stderr — it states the exact expected syntax for the builtin that failed","Open the crushrc file and fix the offending builtin invocation to match the documented syntax","Check HOOKS.md / internal/shellconfig docs for the current builtin signatures (syntax may have changed between versions)","Run the config through 'crush' startup again to confirm the error is gone"],"exampleFix":"// before (.crushrc)\nhook add my-hook\n\n// after (.crushrc) — supply the required event and command arguments\nhook add pre_tool_use ./check.sh","handlingStrategy":"validation","validationCode":"// Validate a crushrc line before running it\nfunc validArgs(name string, args []string) error {\n    switch name {\n    case \"hook\":\n        if len(args) < 2 { return errors.New(\"usage: hook <add|remove> <id ...>\") }\n    case \"lsp\":\n        if len(args) < 1 { return errors.New(\"usage: lsp <add|...> ...\") }\n    case \"option\":\n        if len(args) < 2 { return errors.New(\"usage: option <key> <value>\") }\n    }\n    return nil\n}","typeGuard":null,"tryCatchPattern":"if err := cfg.Load(crushrcPath); err != nil {\n    var usageErr error\n    if strings.Contains(err.Error(), \"usage:\") {\n        usageErr = fmt.Errorf(\"bad crushrc syntax in %s: %w\", crushrcPath, err)\n    }\n    return usageErr\n}","preventionTips":["Copy builtin invocations from documented examples rather than writing from memory","After editing crushrc, run crush once to surface syntax errors before relying on the config","Keep configs under version control so a regression in builtin syntax is easy to diff","Check HOOKS.md / release notes when upgrading — builtin signatures may change"],"tags":["config","shell","crushrc","argument-validation"],"backgroundTag":"invalid-cli-arguments","analyzedSha":"7944b8e52225d8805e31eacbf7ef24856b0dfb7a","analyzedAt":"2026-08-29T12:48:59.079Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}