charmbracelet/glow · error

can't find README in GitLab repository

Error message

can't find README in GitLab repository

What it means

findGitLabREADME calls the GitLab projects API (https://{host}/api/v4/projects/{url-escaped-owner%2Frepo}), reads the readme_url field, and GETs the derived raw URL (readmeRawURL). If either request does not return HTTP 200, glow gives up with this sentinel error instead of a source reader. Like the GitHub variant, it collapses 404/403/other statuses into one message.

Source

Thrown at gitlab.go:60

		return nil, fmt.Errorf("unable to parse json: %w", err)
	}

	readmeRawURL := strings.ReplaceAll(result.ReadmeURL, "blob", "raw")

	if res.StatusCode == http.StatusOK {
		//nolint:bodyclose
		// it is closed on the caller
		resp, err := http.Get(readmeRawURL) //nolint: gosec,noctx
		if err != nil {
			return nil, fmt.Errorf("unable to get url: %w", err)
		}

		if resp.StatusCode == http.StatusOK {
			return &source{resp.Body, readmeRawURL}, nil
		}
	}

	return nil, errors.New("can't find README in GitLab repository")
}

View on GitHub (pinned to e3970c813d)

Solutions

  1. Verify the project URL loads in a browser and shows a README
  2. Pass the raw file URL directly, e.g. glow https://gitlab.com/OWNER/REPO/-/raw/main/README.md
  3. Clone the repository and run glow on the local directory or file
  4. For self-hosted GitLab, confirm anonymous read access to /api/v4/projects/<id> with curl

Example fix

# before
glow https://gitlab.com/owner/typod-repo

# after (raw endpoint bypasses the projects API)
glow https://gitlab.com/owner/repo/-/raw/main/README.md
Defensive patterns

Strategy: validation

Validate before calling

func checkGitLabReadable(u *url.URL) error {
	owner, repo, ok := strings.Cut(strings.TrimPrefix(u.Path, "/"), "/")
	if !ok {
		return fmt.Errorf("invalid url: %s", u)
	}
	api := fmt.Sprintf("https://%s/api/v4/projects/%s", u.Hostname(), url.QueryEscape(owner+"/"+repo))
	resp, err := http.Head(api)
	if err != nil {
		return err
	}
	defer resp.Body.Close()
	if resp.StatusCode != http.StatusOK {
		return fmt.Errorf("gitlab project endpoint returned %d (missing, private, or throttled)", resp.StatusCode)
	}
	return nil
}

Try / catch

src, err := findGitLabREADME(u)
if err != nil {
	if err.Error() == "can't find README in GitLab repository" {
		raw := fmt.Sprintf("https://%s/%s/%s/-/raw/HEAD/README.md", u.Hostname(), owner, repo)
		src, err = openRawSource(raw)
	}
	if err != nil {
		return fmt.Errorf("rendering gitlab readme: %w", err)
	}
}

Prevention

When it happens

Trigger: glow with a gitlab.com repo URL for a project that does not exist or is private (API returns 404); GitLab returning 429/403 for heavy or anonymous traffic from one IP; the raw readme URL returning non-200 because the README was deleted or the branch renamed; self-hosted GitLab where the projects endpoint is disabled or requires auth.

Common situations: Private GitLab projects (glow sends no PRIVATE-TOKEN); typos in the project path; CI shared IPs being throttled by GitLab; README named with an extension GitLab's readme_url does not resolve raw.

Related errors


AI-assisted analysis of charmbracelet/glow@e3970c813d (2026-08-15). Data as JSON: /api/errors/46178d1ef209cb2b. Report an issue: GitHub.