{"record":{"id":"1216aa0e5b24dca2","repo":"browsh-org/browsh","slug":"config-file-error-s","errorCode":null,"errorMessage":"Config file error: %s \n","messagePattern":"Config file error: (.+?) \n","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"interfacer/src/browsh/config.go","lineNumber":91,"sourceCode":"}\n\nfunc setDefaults() {\n\t// Temporary experimental configurable keybindings\n\tviper.SetDefault(\"tty.keys.next-tab\", []string{\"\\u001c\", \"28\", \"2\"})\n}\n\nfunc loadConfig() {\n\tdir := getConfigDir()\n\tfullPath := filepath.Join(dir, configFilename)\n\tslog.Info(\"Looking in \" + fullPath + \" for config.\")\n\tviper.SetConfigType(\"toml\")\n\tviper.SetConfigName(strings.Trim(configFilename, \".toml\"))\n\tviper.AddConfigPath(dir)\n\tviper.AddConfigPath(\".\")\n\tsetDefaults()\n\t// First load the sample config in case the user hasn't updated any new fields\n\tif err := viper.ReadConfig(bytes.NewBuffer([]byte(configSample))); err != nil {\n\t\tpanic(fmt.Errorf(\"Config file error: %s \\n\", err))\n\t}\n\t// Then load the users own config file, overwriting the sample config\n\tif err := viper.MergeInConfig(); err != nil {\n\t\tpanic(fmt.Errorf(\"Config file error: %s \\n\", err))\n\t}\n\tviper.BindPFlags(pflag.CommandLine)\n}\n","sourceCodeStart":73,"sourceCodeEnd":99,"githubUrl":"https://github.com/browsh-org/browsh/blob/499ef386d45cd1e2b5457dd04887c017f77b7e27/interfacer/src/browsh/config.go#L73-L99","documentation":"`loadConfig` first loads an embedded sample config (so new default fields exist) and then merges the user's own .toml over it via `viper.MergeInConfig`. Either read failing causes a panic with `Config file error: <err>`. The first panic (sample config) is effectively an internal bug; the second means the user's config file is missing, unreadable, or malformed TOML.","triggerScenarios":"`Initialise` -> `loadConfig`; `viper.MergeInConfig()` fails because the config file derived from `configFilename`/the `-config` flag doesn't exist, has no read permission, or contains invalid TOML (the sample-config panic only occurs if the embedded sample itself fails to parse).","commonSituations":"Wrong `-config` filename (note `strings.Trim(configFilename, \".toml\")` strips any leading/trailing chars in the set '.tml o', so unusual extensions/names break lookup); hand-edited TOML with syntax errors (missing quotes/brackets); unreadable permissions; running from a directory without the expected config file.","solutions":["Run the TOML through a validator/linter and fix the syntax errors reported in the panic message.","Confirm the file exists and is readable at the resolved location (cwd or the configured dir) and that its name survives the `.toml`-character trimming (stick to a plain `browsh.toml`).","Start with the sample config from the repo, then incrementally add your own settings.","Check file permissions (`chmod u+r config.toml`) if the file exists but can't be read."],"exampleFix":"// before (config.toml, invalid TOML)\nfirefox]\npath = /usr/bin/firefox\n// after\n[firefox]\npath = \"/usr/bin/firefox\"","handlingStrategy":"validation","validationCode":"const fs = require('fs');\nconst configFile = 'browsh.toml';\nif (!fs.existsSync(configFile)) throw new Error(`Config file ${configFile} not found`);\nconst toml = require('@iarna/toml');\ntoml.parse(fs.readFileSync(configFile, 'utf8')); // throws on invalid TOML","typeGuard":null,"tryCatchPattern":"try {\n  startBrowsh();\n} catch (e) {\n  if (/Config file error/.test(e.message)) {\n    console.error('Fix or provide browsh config (.toml):', e.message);\n  } else { throw e; }\n}","preventionTips":["Validate config TOML with a linter before launching browsh.","Keep the config filename simple (e.g. browsh.toml) — the code trims characters in the set '.tml o' from the name.","Start from the repo's sample config and change incrementally.","Check file permissions when the config exists but is unreadable."],"tags":["configuration","toml","viper","startup"],"backgroundTag":"invalid-config-file","analyzedSha":"499ef386d45cd1e2b5457dd04887c017f77b7e27","analyzedAt":"2026-09-02T19:05:32.228Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T21:17:11.164Z"}