{"record":{"id":"6b626cddecc9126b","repo":"ipfs/kubo","slug":"failed-to-set-config-value-s-maybe-use-json","errorCode":null,"errorMessage":"failed to set config value: %s (maybe use --json?)","messagePattern":"failed to set config value: (.+?) \\(maybe use --json\\?\\)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/commands/config.go","lineNumber":596,"sourceCode":"\t// Load full config for resolution\n\tfullCfg, err := r.Config()\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to load config: %q\", err)\n\t}\n\n\t// Expand auto values based on the key\n\texpandedValue := fullCfg.ExpandConfigField(key, value)\n\n\treturn &ConfigField{\n\t\tKey:   key,\n\t\tValue: expandedValue,\n\t}, nil\n}\n\nfunc setConfig(r repo.Repo, key string, value any) (*ConfigField, error) {\n\terr := r.SetConfigKey(key, value)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to set config value: %s (maybe use --json?)\", err)\n\t}\n\treturn getConfig(r, key)\n}\n\n// parseEditorCommand parses the EDITOR environment variable into command and arguments\nfunc parseEditorCommand(editor string) ([]string, error) {\n\treturn shlex.Split(editor, true)\n}\n\nfunc editConfig(filename string) error {\n\teditor := os.Getenv(\"EDITOR\")\n\tif editor == \"\" {\n\t\treturn errors.New(\"ENV variable $EDITOR not set\")\n\t}\n\n\teditorAndArgs, err := parseEditorCommand(editor)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"cannot parse $EDITOR value: %s\", err)","sourceCodeStart":578,"sourceCodeEnd":614,"githubUrl":"https://github.com/ipfs/kubo/blob/329838acdfafae224582930457efe80aa217afc0/core/commands/config.go#L578-L614","documentation":"Wraps an error from `r.SetConfigKey(key, value)` during `ipfs config <key> <value>`. Most often the provided plain-string value cannot be unmarshaled into the config field's Go type (e.g. writing a bare string into a field that expects an array or object). The 'maybe use --json?' hint points at passing the value as JSON so it can be deserialized into the correct type.","triggerScenarios":"`ipfs config Addresses.Swarm '/ip4/...'` — Swarm is an array, so a plain string fails; setting a nested object key with a scalar; setting a value whose type doesn't match the config schema; repo config file not writable.","commonSituations":"Users trying to set array-valued options (Addresses.Swarm, Bootstrap, DNSLink.Resolvers) without --json; setting keys with case mistakes; config read-only because the daemon runs as a different user.","solutions":["Re-run with --json: `ipfs config --json Addresses.Swarm '[\"/ip4/0.0.0.0/tcp/4001\"]'`","Check the field's expected type in docs/config.md and supply matching JSON","For array appends/replacements use `ipfs config --json` with a full array value","Check the underlying error: if it's a permission issue, fix ownership of $IPFS_PATH/config.json (stop the daemon first if it's a lock/permission conflict)"],"exampleFix":"// before\nipfs config Addresses.Swarm /ip4/0.0.0.0/tcp/4001\n// after\nipfs config --json Addresses.Swarm '[\"/ip4/0.0.0.0/tcp/4001\"]'","handlingStrategy":"validation","validationCode":"ipfs config --json Addresses.Swarm '[\"/ip4/0.0.0.0/tcp/4001\"]'  # use --json for non-string fields","typeGuard":null,"tryCatchPattern":"err := r.SetConfigKey(key, value)\nif err != nil {\n    return fmt.Errorf(\"failed to set %s: %w (did you need --json?)\", key, err)\n}","preventionTips":["Use --json whenever the target field is an array, object, number, or boolean (check docs/config.md)","Never hand-edit config.json; use CLI/RPC so type coercion is validated","Stop the daemon or match its user before editing repo files to avoid permission/lock errors","Re-read the value after setting to confirm the stored type: `ipfs config <key>`"],"tags":["config","cli","json"],"backgroundTag":"config-type-mismatch","analyzedSha":"329838acdfafae224582930457efe80aa217afc0","analyzedAt":"2026-09-03T18:30:52.135Z","contentChangedAt":"2026-09-03T18:30:52.135Z","schemaVersion":2},"datasetVersion":"2026-09-11T00:17:11.886Z"}