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

  1. Split the multi-line message: each line is one failed command's error — fix them individually.
  2. Re-run the underlying compose command directly (`docker compose up -d`) for full, ordered output.
  3. Resolve the primary root cause first (often the first line); cascading failures below it are usually downstream symptoms.
  4. 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

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


AI-assisted analysis of jesseduffield/lazydocker@7e7aadc207 (2026-08-15). Data as JSON: /api/errors/b5ae31523b7a7579. Report an issue: GitHub.