wavetermdev/waveterm · error
open and openExternal cannot both be true
Error message
open and openExternal cannot both be true
What it means
PathCommand (pkg/wshrpc/wshserver/wshserver.go:1413) resolves a Wave directory path (config, data, or log) and can open it either in an internal preview block (Open) or via the OS default handler (OpenExternal). These two open modes are mutually exclusive, so the command rejects requests with both flags set rather than picking one arbitrarily. This is a pure client-side request validation error; no I/O occurs before it.
Source
Thrown at pkg/wshrpc/wshserver/wshserver.go:1428
return filestore.WFS.WriteFile(ctx, data.ZoneId, data.FileName, []byte(envStr))
}
func (ws *WshServer) PathCommand(ctx context.Context, data wshrpc.PathCommandData) (string, error) {
pathType := data.PathType
openInternal := data.Open
openExternal := data.OpenExternal
var path string
switch pathType {
case "config":
path = wavebase.GetWaveConfigDir()
case "data":
path = wavebase.GetWaveDataDir()
case "log":
path = filepath.Join(wavebase.GetWaveDataDir(), "waveapp.log")
}
if openInternal && openExternal {
return "", fmt.Errorf("open and openExternal cannot both be true")
}
if openInternal {
_, err := ws.CreateBlockCommand(ctx, wshrpc.CommandCreateBlockData{
TabId: data.TabId,
BlockDef: &waveobj.BlockDef{Meta: map[string]any{
waveobj.MetaKey_View: "preview",
waveobj.MetaKey_File: path,
}},
Ephemeral: true,
Focused: true,
})
if err != nil {
return path, fmt.Errorf("error opening path: %w", err)
}
} else if openExternal {
err := open.Run(path)View on GitHub (pinned to a4447c1563)
Solutions
- Set only one of Open or OpenExternal to true in the PathCommandData before invoking the RPC.
- In CLI usage, pass only one of --open or --open-external.
- In wrapping code, add a guard that clears OpenExternal when Open is set (or return your own validation error) before calling PathCommand.
Example fix
// before
wshclient.PathCommand(ctx, wshrpc.PathCommandData{PathType: "log", Open: true, OpenExternal: true})
// after
wshclient.PathCommand(ctx, wshrpc.PathCommandData{PathType: "log", Open: true}) Defensive patterns
Strategy: validation
Validate before calling
if data.Open && data.OpenExternal {
return fmt.Errorf("specify only one of Open or OpenExternal")
}
// safe to call wshclient.PathCommand(ctx, data) Try / catch
resp, err := wshclient.PathCommand(ctx, data)
if err != nil && strings.Contains(err.Error(), "open and openExternal cannot both be true") {
data.OpenExternal = false
resp, err = wshclient.PathCommand(ctx, data)
} Prevention
- In UI code, make 'open internal' and 'open external' mutually exclusive controls (radio buttons).
- Centralize PathCommandData construction in one helper that normalizes the flags.
- Audit CLI wrappers for flags that can be combined.
When it happens
Trigger: Calling the wsh `path` RPC (or CLI `wsh path --open --open-external <type>`) with both PathCommandData.Open and PathCommandData.OpenExternal = true. PathType may be any of "config", "data", or "log" — the check happens before path resolution matters.
Common situations: CLI/shell aliases that accumulate open flags; scripts that set both flags by default with environment toggles; UI code passing user checkboxes for both 'open in Wave' and 'open in system app' without mutual exclusion.
Understand the failure class
Background: "mutually exclusive" flag errors: what "can't supply both nx and xx", "--raw is not compatible with -i" and "cannot be used with" mean, and how to fix them — this error's family across 29 libraries.
Related errors
- opacity must be between 0.0 and 1.0
- setting background: %v
- update wavobj is nil
- error parsing command map: %w
- invalid oref string: %v
AI-assisted analysis of wavetermdev/waveterm@a4447c1563 (2026-09-01).
Data as JSON: /api/errors/ec8308e2b8d3a3e6.
Report an issue: GitHub.