{"record":{"id":"e63cd2156d4d456f","repo":"syncthing/syncthing","slug":"both-gui-address-and-gui-apikey-should-be-spec","errorCode":null,"errorMessage":"Both --gui-address and --gui-apikey should be specified","messagePattern":"Both --gui-address and --gui-apikey should be specified","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/syncthing/cli/client.go","lineNumber":54,"sourceCode":"\tcfg    config.GUIConfiguration\n\tapikey string\n}\n\ntype apiClientFactory struct {\n\tcfg config.GUIConfiguration\n}\n\nfunc (f *apiClientFactory) getClient() (APIClient, error) {\n\t// Now if the API key and address is not provided (we are not connecting to a remote instance),\n\t// try to rip it out of the config.\n\tif f.cfg.RawAddress == \"\" && f.cfg.APIKey == \"\" {\n\t\tvar err error\n\t\tf.cfg, err = loadGUIConfig()\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t} else if f.cfg.Address() == \"\" || f.cfg.APIKey == \"\" {\n\t\treturn nil, errors.New(\"Both --gui-address and --gui-apikey should be specified\")\n\t}\n\n\thttpClient := http.Client{\n\t\tTransport: &http.Transport{\n\t\t\tTLSClientConfig: &tls.Config{\n\t\t\t\tInsecureSkipVerify: true,\n\t\t\t},\n\t\t\tDialContext: func(_ context.Context, _, _ string) (net.Conn, error) {\n\t\t\t\treturn net.Dial(f.cfg.Network(), f.cfg.Address())\n\t\t\t},\n\t\t},\n\t}\n\treturn &apiClient{\n\t\tClient: httpClient,\n\t\tcfg:    f.cfg,\n\t\tapikey: f.cfg.APIKey,\n\t}, nil\n}","sourceCodeStart":36,"sourceCodeEnd":72,"githubUrl":"https://github.com/syncthing/syncthing/blob/058bcd7334839663cf569501d3ac539034d45cb5/cmd/syncthing/cli/client.go#L36-L72","documentation":"Thrown by the syncthing CLI's api client factory when exactly one of --gui-address / --gui-apikey is set on the command line. The contract is all-or-nothing: either you give both (remote instance) or neither (values are pulled from the local config.xml). One-sided flags are rejected before any HTTP call.","triggerScenarios":"Running e.g. 'syncthing cli show system --gui-address 127.0.0.1:8384' without --gui-apikey, or passing only --gui-apikey. Any 'syncthing cli ...' subcommand that builds an API client hits this.","commonSituations":"Users assume the address alone suffices because the GUI has no auth locally; scripts migrated from older CLI versions that accepted a single flag; copy-pasted examples with the key redacted.","solutions":["Provide both flags together: --gui-address <addr> --gui-apikey <key>","Or drop both flags so the CLI reads GUI address/API key from the local config.xml","Copy the API key from the GUI (Actions > API Key) or <apikey> in config.xml"],"exampleFix":"# before\nsyncthing cli show system --gui-address http://127.0.0.1:8384\n# error: Both --gui-address and --gui-apikey should be specified\n\n# after\nsyncthing cli show system --gui-address http://127.0.0.1:8384 --gui-apikey abc123","handlingStrategy":"validation","validationCode":"// before calling getClient / running the CLI\nif (guiAddress != \"\") != (guiAPIKey != \"\") {\n    return errors.New(\"pass both --gui-address and --gui-apikey, or neither\")\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Wrap the syncthing CLI in scripts that always pass the flag pair (or neither) from one variable","Keep the GUI address and API key together in one env/secret source so they cannot diverge"],"tags":["cli","api","configuration","arguments"],"backgroundTag":null,"analyzedSha":"058bcd7334839663cf569501d3ac539034d45cb5","analyzedAt":"2026-08-15T07:53:43.174Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}