wavetermdev/waveterm · error

unknown status: %q

Error message

unknown status: %q

What it means

WaitForConnect is an exhaustive status switch: Connected returns nil, Connecting keeps polling, Init/Disconnected and Error have dedicated errors, and any other status value falls through to 'unknown status: %q'. Hitting it means DeriveConnStatus returned a status string the waiter doesn't recognize — normally impossible with the built-in status constants, but possible with an unexpected/extended status value.

Source

Thrown at pkg/wslconn/wslconn.go:486

		status := conn.DeriveConnStatus()
		if status.Status == Status_Connected {
			return nil
		}
		if status.Status == Status_Connecting {
			select {
			case <-ctx.Done():
				return fmt.Errorf("context timeout")
			case <-time.After(100 * time.Millisecond):
				continue
			}
		}
		if status.Status == Status_Init || status.Status == Status_Disconnected {
			return fmt.Errorf("disconnected")
		}
		if status.Status == Status_Error {
			return fmt.Errorf("error: %v", status.Error)
		}
		return fmt.Errorf("unknown status: %q", status.Status)
	}
}

// does not return an error since that error is stored inside of WslConn
func (conn *WslConn) Connect(ctx context.Context) error {
	var connectAllowed bool
	conn.WithLock(func() {
		if conn.Status == Status_Connecting || conn.Status == Status_Connected {
			connectAllowed = false
		} else {
			conn.Status = Status_Connecting
			conn.Error = ""
			connectAllowed = true
		}
	})
	log.Printf("Connect %s\n", conn.GetName())
	if !connectAllowed {
		conn.Infof(ctx, "cannot connect to %q when status is %q\n", conn.GetName(), conn.GetStatus())

View on GitHub (pinned to a4447c1563)

Solutions

  1. Log the quoted status value from the error and check it against the status constants defined in this package
  2. Update WaitForConnect (or the status derivation) to handle any newly added status constant
  3. If seen in tests/mocks, fix the mock to return a real status constant
  4. Retry the connection; an unknown transient status typically resolves to a known state on the next poll

Example fix

// before: new status not handled
if status.Status == Status_Error {
    return fmt.Errorf("error: %v", status.Error)
}
// after
if status.Status == Status_Error {
    return fmt.Errorf("error: %v", status.Error)
}
if status.Status == Status_NewConnecting { // handle the new constant
    continue
}
Defensive patterns

Strategy: try-catch

Type guard

func isKnownStatus(s ConnStatus) bool {
    switch s {
    case Status_Connected, Status_Connecting, Status_Init, Status_Disconnected, Status_Error:
        return true
    }
    return false
}

Try / catch

if err := conn.WaitForConnect(ctx); err != nil {
    if strings.HasPrefix(err.Error(), "unknown status:") {
        log.Printf("unrecognized conn status %s — upgrade the client or fix DeriveConnStatus", err)
    }
}

Prevention

When it happens

Trigger: Calling WaitForConnect when DeriveConnStatus yields a status outside the known set (Status_Connected/Connecting/Init/Disconnected/Error) — e.g. after code changes introducing a new status constant without updating WaitForConnect, or a custom/derived status implementation.

Common situations: Running a mismatched build where a new ConnStatus value was added elsewhere but WaitForConnect wasn't updated; mocking DeriveConnStatus in tests with an arbitrary status string.

Related errors


AI-assisted analysis of wavetermdev/waveterm@a4447c1563 (2026-09-01). Data as JSON: /api/errors/3b5c2fe089e69978. Report an issue: GitHub.