Skip to content
Ownership and lifecycle

processownership

Checks that started os/exec commands are waited on or transferred to a wait owner.

Fix offeredNo

What it detects

Tracks commands successfully started with os/exec and reports return paths that neither wait for the process nor transfer the command to code that owns waiting for it.

Checks

Check What it detects
missing-wait
Reports successfully started commands that are neither waited on nor transferred.

Why this is flagged

Starting a process without waiting for it can leave operating-system resources unreleased and loses the process’s final error or exit status. Waiting gives the child process a complete, observable lifecycle.

Further reading: exec.Cmd.Wait.

How to fix it

Use Run when the program can wait immediately. If it must use Start, make sure every successful start is followed by Wait, and handle the resulting exit status or error.

Examples

Flagged code

func run(ctx context.Context) error {
command := exec.CommandContext(ctx, "worker")
// gohawk: started command is not waited on every successful return path
return command.Start()
}

Accepted code

func runSafely(ctx context.Context) error {
command := exec.CommandContext(ctx, "worker")
if err := command.Start(); err != nil {
return err
}
return command.Wait()
}