AlexxIT/go2rtc · error

hass: no token

Error message

hass: no token

What it means

For a direct (non-supervisor) Home Assistant connection, NewClient reads the long-lived access token from the token query parameter and requires it for websocket authentication. An empty token aborts construction with this error before NewAPI is called.

Solutions

  1. Create a long-lived access token in Home Assistant (Profile -> Security -> Long-Lived Access Tokens) and append &token=<TOKEN> to the URL
  2. If running inside a Supervisor add-on, use the URL host 'supervisor' so the SUPERVISOR_TOKEN env is used instead
  3. Check that your config/env expansion actually injects the token value into the query string
  4. Verify the parameter name is exactly token

Example fix

// before
client, err := hass.NewClient("ws://ha.local:8123/api/websocket?entity_id=camera.front")
// after
client, err := hass.NewClient("ws://ha.local:8123/api/websocket?entity_id=camera.front&token=" + longLivedToken)
Defensive patterns

Strategy: validation

Validate before calling

u, _ := url.Parse(rawURL)
if u != nil && u.Host != "supervisor" && u.Query().Get("token") == "" && os.Getenv("SUPERVISOR_TOKEN") == "" {
    return errors.New("direct HA connection requires a long-lived access token in the URL")
}

Type guard

func hasToken(rawURL string) bool {
    u, err := url.Parse(rawURL)
    return err == nil && (u.Host == "supervisor" || u.Query().Get("token") != "")
}

Try / catch

client, err := hass.NewClient(rawURL)
if err != nil {
    if strings.Contains(err.Error(), "no token") {
        return fmt.Errorf("missing Home Assistant access token: %w", err)
    }
    return err
}

Prevention

When it happens

Trigger: Calling hass.NewClient with a non-supervisor URL (host != 'supervisor') whose query string lacks a token parameter or has token= empty. Note: when host is 'supervisor' the token is obtained from SUPERVISOR_TOKEN env instead, so this error only applies to direct connections.

Common situations: Running outside the HA Supervisor add-on environment while still omitting the token; using a URL copied from supervisor docs; token env var not expanded into the URL; long-lived access token not created in HA profile settings.

Understand the failure class

Background: "API key is required" / "API key not found" / "No API key was set": the missing-api-key error family across 16 libraries — this error's family across 16 libraries.

Related errors


AI-assisted analysis of AlexxIT/go2rtc@c245815e75 (2026-09-07). Data as JSON: /api/errors/3ad0b4300a1de726. Report an issue: GitHub.

Appendix: source

Thrown at pkg/hass/client.go:40

	query := u.Query()

	entityID := query.Get("entity_id")
	if entityID == "" {
		return nil, errors.New("hass: no entity_id")
	}

	var uri, token string

	if u.Host == "supervisor" {
		uri = "ws://supervisor/core/websocket"
		token = SupervisorToken()
	} else {
		uri = "ws://" + u.Host + "/api/websocket"
		token = query.Get("token")
	}

	if token == "" {
		return nil, errors.New("hass: no token")
	}

	// 1. Check connection to Hass
	hassAPI, err := NewAPI(uri, token)
	if err != nil {
		return nil, err
	}

	defer hassAPI.Close()

	// 2. Create WebRTC client
	rtcAPI, err := webrtc.NewAPI()
	if err != nil {
		return nil, err
	}

	conf := pion.Configuration{}
	pc, err := rtcAPI.NewPeerConnection(conf)

View on GitHub (pinned to c245815e75)