jesseduffield/lazydocker · error
{joined stderr}
Error message
{joined stderr} What it means
This is the tail of the parallel-command runner in pkg/commands/os.go: several commands run concurrently (each goroutine logs its Wait() error and appends to finalErrors), and if any failed, all collected error strings are joined with newlines into one error. The '{joined stderr}' placeholder means 'one or more subprocess failure messages concatenated'. It is the aggregate failure report for batch operations like `docker-compose up -d` across services.
Source
Thrown at pkg/commands/os.go:362
if b, err := io.ReadAll(stderr); err == nil {
if len(b) > 0 {
finalErrors = append(finalErrors, string(b))
}
}
if err := currentCmd.Wait(); err != nil {
c.Log.Error(err)
}
wg.Done()
}()
}
wg.Wait()
if len(finalErrors) > 0 {
return errors.New(strings.Join(finalErrors, "\n"))
}
return nil
}
// Kill kills a process. If the process has Setpgid == true, then we have anticipated that it might spawn its own child processes, so we've given it a process group ID (PGID) equal to its process id (PID) and given its child processes will inherit the PGID, we can kill that group, rather than killing the process itself.
func (c *OSCommand) Kill(cmd *exec.Cmd) error {
return kill.Kill(cmd)
}
// PrepareForChildren sets Setpgid to true on the cmd, so that when we run it as a subprocess, we can kill its group rather than the process itself. This is because some commands, like `docker-compose logs` spawn multiple children processes, and killing the parent process isn't sufficient for killing those child processes. We set the group id here, and then in subprocess.go we check if the group id is set and if so, we kill the whole group rather than just the one process.
func (c *OSCommand) PrepareForChildren(cmd *exec.Cmd) {
kill.PrepareForChildren(cmd)
}
View on GitHub (pinned to 7e7aadc207)
Solutions
- Split the multi-line message: each line is one failed command's error — fix them individually.
- Re-run the underlying compose command directly (`docker compose up -d`) for full, ordered output.
- Resolve the primary root cause first (often the first line); cascading failures below it are usually downstream symptoms.
- For port conflicts / missing images called out in the message, fix the compose file and retry the operation.
Defensive patterns
Strategy: try-catch
Try / catch
err := osCommand.RunCommandsInParallel(cmds)
if err != nil {
for _, line := range strings.Split(err.Error(), "\n") {
log.Error("parallel cmd failure: " + line) // handle each individually
}
} Prevention
- Validate compose files and prerequisites before batch operations so partial failures are rare.
- Treat a joined error as N independent failures; split on newlines before display.
- Re-run bulk operations after fixing the first root cause — later lines are often cascading failures.
When it happens
Trigger: RunCommandsInParallel / RunCommandWithPlatformContext-style API where at least one queued command exits non-zero; each goroutine's cmd.Wait() error or captured output lands in finalErrors and is joined.
Common situations: Docker-compose failing to build or start one service out of several (bad Dockerfile, port conflict, missing image); parallel prune/remove commands where one container is already gone; bulk operations where partial success makes the joined message confusing.
Related errors
- {stderr}
- Cannot proceed until docker gives us more information about
- Container does not support attaching. You must either run th
- You cannot attach to a stopped container, you need to start
- container is not running
AI-assisted analysis of jesseduffield/lazydocker@7e7aadc207 (2026-08-15).
Data as JSON: /api/errors/b5ae31523b7a7579.
Report an issue: GitHub.