go-delve/delve · error

could not open stdin file: %v

Error message

could not open stdin file: %v

What it means

The DAP launch request supports 'stdinFrom' to redirect the debuggee's stdin from a file. Delve opens that file with os.Open before starting the process; if the open fails (missing file, permission denied, is-a-directory), this error is returned and the debug session fails to launch. Note cmd.Stdin defaults to os.Stdin when stdinFrom is empty.

Source

Thrown at service/dap/server.go:1420

		return "."
	}
	return string(bytes.TrimSpace(out))
}

// newNoDebugProcess is called from onLaunchRequest (run goroutine) and
// requires holding mu lock. It prepares process exec.Cmd to be started.
func (s *Session) newNoDebugProcess(program string, targetArgs []string, wd string, remoteOut bool, stdinFrom, stdoutTo, stderrTo string) (cmd *exec.Cmd, stdoutReader, stderrReader io.ReadCloser, err error) {
	if s.noDebugProcess != nil {
		return nil, nil, nil, errors.New("another launch request is in progress")
	}

	cmd = exec.Command(program, targetArgs...)
	cmd.Stdin, cmd.Dir = os.Stdin, wd

	if stdinFrom != "" {
		fh, err := os.Open(stdinFrom)
		if err != nil {
			return nil, nil, nil, fmt.Errorf("could not open stdin file: %v", err)
		}
		cmd.Stdin = fh
	}

	if remoteOut {
		if stderrReader, err = cmd.StderrPipe(); err != nil {
			return nil, nil, nil, err
		}

		if stdoutReader, err = cmd.StdoutPipe(); err != nil {
			return nil, nil, nil, err
		}
	} else {
		var err error
		toclose := []*os.File{}
		create := func(redirect string, dflt *os.File) (f *os.File) {
			if redirect != "" {
				f, err = os.Create(redirect)

View on GitHub (pinned to a23773e6c3)

Solutions

  1. Verify the stdinFrom path exists and is readable by the user running delve (ls -l / test -r).
  2. Use an absolute path, or a path correct relative to the DAP server's working directory.
  3. Ensure it is a regular file, not a directory.
  4. In remote/container setups, make sure the file exists on the machine where dlv runs, not just the client.

Example fix

// before (launch.json)
"stdinFrom": "./input.txt"
// after
"stdinFrom": "/absolute/path/to/input.txt"
Defensive patterns

Strategy: validation

Validate before calling

info, err := os.Stat(cfg.StdinFrom)
if err != nil {
    return fmt.Errorf("stdinFrom unreachable: %w", err)
}
if info.IsDir() {
    return errors.New("stdinFrom must be a regular file")
}
f, err := os.Open(cfg.StdinFrom)
if err != nil {
    return fmt.Errorf("stdinFrom not readable: %w", err)
}
f.Close()

Prevention

When it happens

Trigger: A DAP launch/attach request with attribute stdinFrom pointing to a nonexistent path, a path without read permission, a directory, or a path relative to a different working directory than the client's.

Common situations: Typos in the launch.json 'stdinFrom' value; file deleted between launches; using a client-side relative path that doesn't resolve where dlv runs; trying to feed a directory or unreadable device node; container/remote debugging where the path exists on the client but not the host running dlv.

Understand the failure class

Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.

Related errors


AI-assisted analysis of go-delve/delve@a23773e6c3 (2026-08-31). Data as JSON: /api/errors/2563b6eed6203344. Report an issue: GitHub.