opentofu/opentofu · warning
%s: %w
Error message
%s: %w
What it means
Returned by the exec-based browser launcher when the program named in the BROWSER environment variable exits non-zero or cannot be run. The launcher (used by 'tofu login' to open the browser for device/OAuth flows) builds an exec.Cmd with the BROWSER value as the executable and the URL as its only argument, and wraps any cmd.Run() failure as "<execPath>: <cause>".
Source
Thrown at internal/command/webbrowser/exec.go:45
func NewExecLauncher(execPath string) Launcher {
return execLauncher{
execPath: execPath,
}
}
type execLauncher struct {
execPath string
}
func (l execLauncher) OpenURL(url string) error {
cmd := &exec.Cmd{
Path: l.execPath,
Args: []string{l.execPath, url},
Env: os.Environ(),
}
err := cmd.Run()
if err != nil {
return fmt.Errorf("%s: %w", l.execPath, err)
}
return nil
}
// ParseBrowserEnv takes the raw value of a BROWSER environment variable and
// attempts to parse it as a reference to an executable, whose absolute
// path is returned if successful. Returns an empty string if the value cannot
// be interpreted as an executable to run.
//
// This implements the simple form of this environment variable commonly used
// by software on Unix-like systems, where the value must be literally just
// a command to run whose first and only argument would be the URL to open.
//
// It does NOT support the more complex interpretation of that environment
// variable that was proposed at http://www.catb.org/~esr/BROWSER/ , because
// that form has not been widely implemented and the implementations that
// exist do not have consistent behavior due to the proposal being
// ambiguous.View on GitHub (pinned to 3561785c48)
Solutions
- Unset BROWSER (or set it to a real, working browser command) and re-run 'tofu login'
- If the auto-open fails, copy the printed URL and open it manually on any machine, then paste the code back - the login flow supports this
- On headless machines use BROWSER=echo or similar so the URL is just printed
- Verify the browser binary exists and is executable: which $BROWSER
Example fix
# before BROWSER=firefox tofu login # fails: firefox: exec format error / not found # after BROWSER=echo tofu login # prints URL to terminal for manual opening # or: unset BROWSER; tofu login
Defensive patterns
Strategy: fallback
Validate before calling
# Before 'tofu login', confirm BROWSER is executable if set
if [ -n "$BROWSER" ] && ! command -v "${BROWSER%% *}" >/dev/null 2>&1; then
echo "BROWSER=$BROWSER is not runnable; falling back to manual URL" >&2
BROWSER=echo tofu login
else
tofu login
fi Type guard
func browserLaunchErr(err error) bool {
// exec.go wraps as "<execPath>: %w" - match on ': exec:' or exit-error shapes
return err != nil && (strings.Contains(err.Error(), ": exec:") || strings.Contains(err.Error(), "exit status"))
} Try / catch
err := browser.OpenURL(url)
if err != nil {
// non-fatal by design: show the URL and continue the login flow manually
fmt.Printf("Could not open browser automatically (%v)\nVisit this URL: %s\n", err, url)
} Prevention
- Set BROWSER to something guaranteed to work headless (echo, or a real GUI browser on desktops)
- Never depend on browser auto-open in automation - always plan for copy/paste of the login URL
- Test 'tofu login' once per environment (container/CI) during setup, not during deployments
When it happens
Trigger: 'tofu login' (or anything calling webbrowser.OpenURL) with BROWSER set to a command that fails to launch: binary not found ($PATH lookup failure), not executable, or the browser process returns a non-zero exit status (common on headless systems with browsers like w3m that fail without a display).
Common situations: SSH sessions or containers where BROWSER is set to something that needs a GUI; stale BROWSER value pointing at a removed browser; CI environments where 'tofu login' is attempted non-interactively.
Related errors
- Failed to generate lineage: %w
- default workspace not supported You can create a new workspa
- workspaces not supported
- could not find storage endpoint in given metadata host
- could not find token audience in given metadata host
AI-assisted analysis of opentofu/opentofu@3561785c48 (2026-08-15).
Data as JSON: /api/errors/46743baff8bda74d.
Report an issue: GitHub.