{"record":{"id":"b96491d3d4a9f42e","repo":"charmbracelet/crush","slug":"failed-to-get-data-directory-v-b96491","errorCode":null,"errorMessage":"failed to get data directory: %v","messagePattern":"failed to get data directory: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/cmd/server.go","lineNumber":33,"sourceCode":"\t\"github.com/charmbracelet/crush/internal/server\"\n\t\"github.com/charmbracelet/x/term\"\n\t\"github.com/spf13/cobra\"\n)\n\nvar serverHost string\n\nfunc init() {\n\tserverCmd.Flags().StringVarP(&serverHost, \"host\", \"H\", server.DefaultHost(), \"Server host (TCP or Unix socket)\")\n\trootCmd.AddCommand(serverCmd)\n}\n\nvar serverCmd = &cobra.Command{\n\tUse:   \"server\",\n\tShort: \"Start the Crush server\",\n\tRunE: func(cmd *cobra.Command, _ []string) error {\n\t\tdataDir, err := cmd.Flags().GetString(\"data-dir\")\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"failed to get data directory: %v\", err)\n\t\t}\n\t\tdebug, err := cmd.Flags().GetBool(\"debug\")\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"failed to get debug flag: %v\", err)\n\t\t}\n\n\t\tcfg, err := config.Load(config.GlobalWorkspaceDir(), dataDir, debug)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"failed to load configuration: %v\", err)\n\t\t}\n\n\t\thostURL, err := server.ParseHostURL(serverHost)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"invalid server host: %v\", err)\n\t\t}\n\n\t\tlogFile := filepath.Join(config.GlobalCacheDir(), \"server-\"+safeHostName(hostURL), \"crush.log\")\n","sourceCodeStart":15,"sourceCodeEnd":51,"githubUrl":"https://github.com/charmbracelet/crush/blob/7944b8e52225d8805e31eacbf7ef24856b0dfb7a/internal/cmd/server.go#L15-L51","documentation":"The `crush server` command reads its --data-dir flag via cmd.Flags().GetString. This error wraps any failure of that lookup, which only happens if the flag was not registered (or registered with the wrong type) on the command — a wiring bug, not a user input problem.","triggerScenarios":"Running `crush server` with a binary where the `data-dir` flag registration was removed/renamed in init(), or invoking the RunE logic on a different command that lacks the flag.","commonSituations":"Custom builds or forks with modified flag setup; calling serverCmd's RunE from tests or other commands without the flag bound; mix-and-match binary/plugin versions.","solutions":["Install an official, unmodified release of Crush; a stock binary always registers --data-dir.","If building from source, check the serverCmd flag registration in internal/cmd/server.go is intact (flags.String(\"data-dir\", ...)).","If invoking RunE programmatically, define the flag on the command first via serverCmd.Flags().String(...)."],"exampleFix":"// before\n// flag never registered\nserverCmd.RunE(cmd, args)\n// after\nserverCmd.Flags().String(\"data-dir\", \"\", \"data directory\")\nserverCmd.RunE(cmd, args)","handlingStrategy":"validation","validationCode":"if serverCmd.Flags().Lookup(\"data-dir\") == nil {\n    return fmt.Errorf(\"data-dir flag not registered on this build\")\n}","typeGuard":"func hasFlag(cmd *cobra.Command, name string) bool { return cmd.Flags().Lookup(name) != nil }","tryCatchPattern":"if err := serverCmd.RunE(serverCmd, args); err != nil {\n    if strings.HasPrefix(err.Error(), \"failed to get data directory\") {\n        return fmt.Errorf(\"binary is missing the data-dir flag; use an official build\")\n    }\n    return err\n}","preventionTips":["Use official Crush binaries or verify flag registration survives your forks.","Add a smoke test that executes serverCmd with a flag set.","Never call a command's RunE from code without registering its flags first."],"tags":["cli","flags","cobra"],"backgroundTag":"flag-not-defined","analyzedSha":"7944b8e52225d8805e31eacbf7ef24856b0dfb7a","analyzedAt":"2026-08-29T12:48:59.079Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}