{"record":{"id":"b9dd888e0b86b873","repo":"matryer/xbar","slug":"write-default-variables","errorCode":null,"errorMessage":"write default variables","messagePattern":"write default variables","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/plugins/install.go","lineNumber":149,"sourceCode":"\t\tif f.Filename != plugin.Filename {\n\t\t\tcontinue\n\t\t}\n\t\tif err := os.Chmod(pluginFile, 0755); err != nil {\n\t\t\treturn errors.Wrap(err, \"set executable permission on plugin entry point\")\n\t\t}\n\t\t// write the default variables\n\t\tplugin, err := metadata.Parse(metadata.DebugfNoop, pluginFile, f.Content)\n\t\tif err != nil {\n\t\t\tlog.Println(\"install plugin: unable to parse metadata:\", err)\n\t\t}\n\t\tif len(plugin.Vars) > 0 {\n\t\t\tdefaultVars := make(map[string]interface{})\n\t\t\tfor _, pluginVar := range plugin.Vars {\n\t\t\t\tdefaultVars[pluginVar.Name] = pluginVar.DefaultValue()\n\t\t\t}\n\t\t\terr := SaveVariableValues(i.PluginDir, pluginFile, defaultVars)\n\t\t\tif err != nil {\n\t\t\t\treturn errors.Wrap(err, \"write default variables\")\n\t\t\t}\n\t\t}\n\t}\n\treturn nil\n}\n","sourceCodeStart":131,"sourceCodeEnd":155,"githubUrl":"https://github.com/matryer/xbar/blob/d624239058997c80118eaebe2e7f8331b3c765e0/pkg/plugins/install.go#L131-L155","documentation":"Returned by writePluginFiles when SaveVariableValues fails to persist the plugin's declared default variable values next to the installed plugin file. This happens after a successful install when the parsed plugin metadata declares vars, and the variable store cannot be written. The plugin files themselves are already installed, so the failure leaves a partially initialized plugin.","triggerScenarios":"Installer.Install -> writePluginFiles, for entry-point files whose parsed metadata declares Vars, when SaveVariableValues(i.PluginDir, pluginFile, defaultVars) fails — typically because i.PluginDir is not writable or the plugin's own variable file is corrupt/locked.","commonSituations":"Read-only or quota-limited plugin directory; PluginDir configured differently between install and variable-save; concurrent installs racing on the same variable store file.","solutions":["Check that i.PluginDir exists and is writable by the current user (mkdir -p, chown).","Inspect the variable store file for corruption or locks and repair/remove it.","Re-run the install after fixing the directory; the plugin will be re-created with fresh defaults."],"exampleFix":"// before\ninstaller := plugins.Installer{PluginDir: \"/var/lib/upterm/plugins\"} // not writable by user\n// after\nhome, _ := os.UserHomeDir()\ninstaller := plugins.Installer{PluginDir: filepath.Join(home, \".upterm\", \"plugins\")}","handlingStrategy":"try-catch","validationCode":"func ensurePluginDirWritable(dir string) error {\n    if err := os.MkdirAll(dir, 0755); err != nil { return err }\n    f, err := os.CreateTemp(dir, \".var-test\")\n    if err != nil { return err }\n    f.Close(); os.Remove(f.Name())\n    return nil\n}","typeGuard":null,"tryCatchPattern":"err := installer.Install(plugin)\nif err != nil && strings.Contains(err.Error(), \"write default variables\") {\n    log.Printf(\"plugin installed but defaults not saved: %v\", err)\n    // fallback: re-run SaveVariableValues after fixing PluginDir permissions\n}\nreturn err","preventionTips":["Keep PluginDir consistent between install and variable-save paths (same config).","Ensure PluginDir is writable at startup; pre-create it.","Avoid concurrent installs of the same plugin.","Handle partial installs: on failure, remove the partially installed plugin file before retrying."],"tags":["go","filesystem","plugin-install","variables"],"backgroundTag":"plugin-variable-store-write-failed","analyzedSha":"d624239058997c80118eaebe2e7f8331b3c765e0","analyzedAt":"2026-09-02T22:38:22.007Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-10T02:17:09.455Z"}