Subsequent job traces fail to load after the first call to RunTraceSha()
Checklist
-
I'm using the latest version of the extension (Run glab --version)- Extension version:
-
glab 1.67.0 (1e957280)(homebrew) -
glab 1.67.0 (90f42d15)(local build frommain)
-
- Extension version:
-
Operating system and version: MacOS Sequoia 15.6 -
Gitlab.com or self-managed instance? gitlab.com -
GitLab version (if self-managed) N/A -
I have performed glab auth statusto check for authentication issues -
Run the command in debug mode (like DEBUG=true glab mr list) and attach any useful output
Summary
In glab ci view, global state variables in ciutils.RunTraceSha() cause subsequent job log views in the same session to display incorrect log output (sometimes empty), most likely due to a globally-scoped offset variable that should be scoped per-call
Environment
- OS: Darwin 24.6.0 arm64
- SHELL: /bin/zsh
- TERM: xterm-256color
- GLAB: glab 1.67.0 (1e957280)
Other:
Steps to reproduce
- Open
glab ci viewfor any pipeline with multiple jobs - Press Enter on the first job to view its logs (logs display correctly)
- Press Escape to close the first job's logs
- Navigate to a different job and press Enter to view its logs
- Observe that only "Getting job trace..." appears instead of the full log content
- this happens if the first job's log length is much greater than the second log's content
- Also: the text should appear for each job, but is only shown on the first invocation
What is the current bug behavior?
- First job logs display correctly with the line
Showing logs for [Name] job #[ID].and the full log content - Second and subsequent job logs show only "Getting job trace..." (22 characters)
- The logs appear to "hang" showing just the placeholder text
-
RunTraceShacompletes successfully but TextView only contains the placeholder text
What is the expected correct behavior?
- All job logs should display their full content regardless of how many job logs have been viewed previously in the same session
- Each job's logs should be independent and show complete trace output
Relevant logs and/or screenshots
I added debug logging to runTraceSha() and followed the steps above to reproduce:
[DEBUG] First job - runTraceSha completed, content length: 96048 ✅
[DEBUG] Second job - runTraceSha completed, content length: 22 ❌
Note that "Getting job trace..." is 22 characters, and is the only text emitted from RunTraceSha on subsequent executions.
Possible fixes
I believe the root cause for both issues (log truncation and the omission of the "Showing logs for..." line) is using globally-scoped variables:
in internal/commands/ci/ciutils/utils.go:27
var (
once sync.Once
offset int64
)
in internal/commands/ci/ciutils/utils.go:92
// Note: runTraceSha wraps runTrace
func runTrace(ctx context.Context, apiClient *gitlab.Client, w io.Writer, pid any, jobId int) error {
fmt.Fprintln(w, "Getting job trace...")
for range time.NewTicker(time.Second * 3).C {
[...]
once.Do(func() { // ISSUE 1
fmt.Fprintf(w, "Showing logs for %s job #%d.\n", job.Name, job.ID)
})
trace, _, err := apiClient.Jobs.GetTraceFile(pid, jobId)
if err != nil || trace == nil {
return errors.Wrap(err, "failed to find job")
}
_, _ = io.CopyN(io.Discard, trace, offset)
lenT, err := io.Copy(w, trace)
[...]
offset += lenT // ISSUE 2
}
return nil
In the snippet above, there are two issues:
-
once.Do()is guaranteed to execute exactly once, no matter how many times it's called, which means the text "Showing logs for..." will only appear the first time job logs are retrieved. - Because
offsetis a global, in subsequent calls torunTrace(), the value ofoffsetmight be greater than the length of the log that is loaded. At best, this will truncate the beginning of the subsequent log text. At worst, it will skip the entire content of the log file
Edited by Ryan Taylor
