nikivdev/code · error
Could not determine GitHub username
Error message
Could not determine GitHub username
What it means
run_github shells out to `gh api user -q .login` to learn the authenticated GitHub username, used as the default owner for the new repository. If the command succeeds but prints nothing (empty stdout), the tool cannot name an owner and bails with this error. It usually means `gh` is not authenticated even though an earlier auth check appeared to pass, or the token has no user scope.
Source
Thrown at src/publish.rs:148
let cwd = std::env::current_dir()?;
let folder_name = cwd
.file_name()
.and_then(|n| n.to_str())
.unwrap_or("repo")
.to_string();
// Check if already a git repo
let is_git_repo = cwd.join(".git").exists();
// Get GitHub username (fallback owner)
let gh_user = Command::new("gh")
.args(["api", "user", "-q", ".login"])
.output()
.context("failed to get GitHub username")?;
let username = String::from_utf8_lossy(&gh_user.stdout).trim().to_string();
if username.is_empty() {
bail!("Could not determine GitHub username");
}
let mut owner = opts.owner.clone().unwrap_or_else(|| username.clone());
let mut repo_name_from_url: Option<String> = None;
let mut remote_from_url: Option<String> = None;
if let Some(url) = opts.url.as_ref() {
let (parsed_owner, parsed_name, parsed_remote) = parse_github_repo(url)?;
owner = parsed_owner;
repo_name_from_url = Some(parsed_name);
remote_from_url = Some(parsed_remote);
}
// Determine repo name
let repo_name = if let Some(name) = opts.name {
name
} else if let Some(name) = repo_name_from_url.clone() {
name
} else if opts.yes {
folder_name.clone()View on GitHub (pinned to a747e741ae)
Solutions
- Run `gh api user -q .login` manually; if empty, run `gh auth login` (or `gh auth login --hostname <host>`) to re-authenticate
- Check `gh auth status` and verify the correct host and token scopes (needs `repo`/`user`)
- If GH_TOKEN/GITHUB_TOKEN is set in the environment, verify the token is valid and has read:user scope, or unset it so `gh` uses its stored credentials
- Pass `--owner <name>` to publish so the username lookup is not needed for the owner
Example fix
// before (CI) export GH_TOKEN=ghp_expiredtoken f publish // after: refresh the token or authenticate interactively gh auth login # or pass owner explicitly f publish --owner myuser
Defensive patterns
Strategy: validation
Validate before calling
let out = std::process::Command::new("gh").args(["api","user","-q",".login"]).output()?;
let login = String::from_utf8_lossy(&out.stdout).trim().to_string();
if !out.status.success() || login.is_empty() {
eprintln!("gh is not authenticated; run `gh auth login` first");
std::process::exit(1);
} Try / catch
match run_github(opts) {
Err(e) if e.to_string().contains("Could not determine GitHub username") => {
eprintln!("Run `gh auth login`, or pass --owner <name> to skip the lookup");
}
other => other?,
} Prevention
- Run `gh auth status` before scripting publish commands
- Avoid scope-less/expired GH_TOKEN env vars in CI; rotate tokens regularly
- Pass --owner explicitly in automation to skip the username lookup
When it happens
Trigger: `gh api user -q .login` returns exit 0 with empty stdout: e.g. a GH_TOKEN/GITHUB_TOKEN env var is set to an invalid or scope-less token, `gh` is authenticated to a non-GitHub (GHES) host with no user, or `gh auth login` was skipped while a stub `gh` is on PATH.
Common situations: CI containers where GH_TOKEN is set but expired/revoked; gh authenticated against a different hostname than expected; running after `gh auth logout`; a wrapper script shadowing `gh` that outputs nothing on stdout.
Related errors
- Failed to create repository
- `gh` is installed but not working
- gh {} failed: {}
- unable to determine GitHub repo (origin URL not GitHub, and
- failed to determine PR URL after creation (gh output had no
AI-assisted analysis of nikivdev/code@a747e741ae (2026-09-01).
Data as JSON: /api/errors/434cc0b2bf8c3d68.
Report an issue: GitHub.