Skip to content

remote: Invalid username or token. Password authentication is not supported for Git operations. #165

Description

@suzuki-shunsuke

ghtkn info

$ ghtkn -v
ghtkn version 0.2.2

Overview

Git Credential Helper fails when the user access token has expired.
But if we run the command immediately again, the command succeeds.

How to reproduce

~/.gitconfig

[credential]
	helper = !ghtkn git-credential
	useHttpPath = true

Command:

Run git push or git pull.

git pull

Expected behaviour

Git Credential Helper works fine.

Actual behaviour

The command fails.

remote: Invalid username or token. Password authentication is not supported for Git operations.
fatal: Authentication failed for 'https://github.com/<redacted>/<redacted>/'

But if we run the same command immediately, the command succeeds.

The application uses the device flow to generate your GitHub User Access Token.
Copy your one-time code: <redacted>
This code is valid until 2025-11-17T09:55:14+09:00
https://github.com/login/device will open automatically after a few seconds...

Note

This is the problem of Git Credential Helper.
Maybe Git doesn't pass path to the credential helper for some reason.

func (r *runner) readStdinForGitCredentialHelper(ctx context.Context) (*scanResult, error) { //nolint:cyclop
inputCh := make(chan *scanResult, 1)
go func() {
scanner := bufio.NewScanner(r.stdin)
result := &scanResult{}
for scanner.Scan() {
line := scanner.Text()
if line == "" {
break // empty line means the end of input
}
key, value, ok := strings.Cut(line, "=")
if !ok {
continue // ignore invalid stdin
}
switch key {
case "protocol":
result.Protocol = value
case "host":
result.Host = value
case "username":
result.Username = value
case "path":
// path is used to switch GitHub Apps by repository
// But path may not be passed.
// To guarantee the path is passed, you can configure Git like below:
//
// $ git config credential.useHttpPath true
result.Path = value
result.Owner = strings.Split(value, "/")[0]
case "password":
result.Password = value
default:
continue // ignore unknown keys
}
}
result.Err = scanner.Err()
inputCh <- result
close(inputCh)
}()
select {
case <-ctx.Done():
return nil, ctx.Err() //nolint:wrapcheck
case result := <-inputCh:
return result, result.Err
}
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions