{"record":{"id":"42e7ec195c612b7b","repo":"cli/cli","slug":"loading-ssh-config-w","errorCode":null,"errorMessage":"loading ssh config: %w","messagePattern":"loading ssh config: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/cmd/codespace/ssh.go","lineNumber":513,"sourceCode":"\tsshGCmd := exec.CommandContext(ctx, sshExe, sshGArgs...)\n\tconfigBytes, err := sshGCmd.Output()\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"could not load ssh configuration: %w\", err)\n\t}\n\n\tconfigLines := strings.Split(string(configBytes), \"\\n\")\n\tfor _, line := range configLines {\n\t\tline = strings.TrimSpace(line)\n\n\t\tif strings.HasPrefix(line, \"identityfile \") {\n\t\t\tprivateKeyPath := strings.SplitN(line, \" \", 2)[1]\n\n\t\t\tkeypair, err := keypairForPrivateKey(privateKeyPath)\n\t\t\tif errors.Is(err, errKeyFileNotFound) {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif err != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"loading ssh config: %w\", err)\n\t\t\t}\n\n\t\t\treturn keypair, nil\n\t\t}\n\t}\n\n\treturn nil, errKeyFileNotFound\n}\n\n// keypairForPrivateKey returns the KeyPair with the specified private key if it and the public key both exist\nfunc keypairForPrivateKey(privateKeyPath string) (*ssh.KeyPair, error) {\n\tif strings.HasPrefix(privateKeyPath, \"~\") {\n\t\tuserHomeDir, err := os.UserHomeDir()\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"getting home dir: %w\", err)\n\t\t}\n\n\t\t// os.Stat can't handle ~, so convert it to the real path","sourceCodeStart":495,"sourceCodeEnd":531,"githubUrl":"https://github.com/cli/cli/blob/0eeec0b92edbe70199f9768522f831d3534f41ad/pkg/cmd/codespace/ssh.go#L495-L531","documentation":"Returned by firstConfiguredKeyPair while scanning 'ssh -G' output for identityfile entries: the first configured IdentityFile was found, but keypairForPrivateKey failed on it for a reason other than the file not existing (which is skipped with continue). This means the key path exists but cannot be turned into a usable KeyPair.","triggerScenarios":"An 'identityfile <path>' line is present in the ssh -G output and keypairForPrivateKey(privateKeyPath) returns an error that is not errKeyFileNotFound, e.g. os.UserHomeDir() failing while expanding a '~' prefixed path.","commonSituations":"HOME or USERPROFILE environment variable unset so '~/.ssh/id_rsa' cannot expand; key path with '~' in a position where replacement produces an invalid path.","solutions":["Ensure HOME (Unix) / USERPROFILE (Windows) is set in the shell running gh","Replace '~'-relative IdentityFile paths with absolute paths in ssh config","Check the wrapped error text to see which key path failed and fix or remove that IdentityFile entry"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"if os.Getenv(\"HOME\") == \"\" && runtime.GOOS != \"windows\" {\n    return errors.New(\"HOME unset; tilde IdentityFile paths cannot expand\")\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Prefer absolute paths in IdentityFile entries","Always run gh with a fully initialized login environment (HOME set)"],"tags":["go","codespaces","ssh","config","environment"],"backgroundTag":null,"analyzedSha":"0eeec0b92edbe70199f9768522f831d3534f41ad","analyzedAt":"2026-08-15T12:31:05.478Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}