wtfutil/wtf · error
client could not be initialized
Error message
client could not be initialized
What it means
digitalocean widget.Fetch() requires a configured DigitalOcean API client (widget.client). If client initialization failed earlier (typically a missing or invalid DIGITALOCEAN_ACCESS_TOKEN), client stays nil and Fetch returns this error instead of dereferencing nil. The widget has no droplet client to query with.
Source
Thrown at modules/digitalocean/widget.go:70
}
widget.initializeKeyboardControls()
widget.View.SetScrollable(true)
widget.SetRenderFunction(widget.display)
widget.createClient()
return &widget
}
/* -------------------- Exported Functions -------------------- */
// Fetch retrieves droplet data
func (widget *Widget) Fetch() error {
if widget.client == nil {
return errors.New("client could not be initialized")
}
var err error
widget.droplets, err = widget.dropletsFetch()
return err
}
// Next selects the next item in the list
func (widget *Widget) Next() {
widget.ScrollableWidget.Next()
}
// Prev selects the previous item in the list
func (widget *Widget) Prev() {
widget.ScrollableWidget.Prev()
}
// Refresh updates the data for this widget and displays it onscreenView on GitHub (pinned to bb838c1ccb)
Solutions
- Export DIGITALOCEAN_ACCESS_TOKEN with a valid read-scoped token in the environment wtfutil launches from
- Check the widget's token configuration in config.yml matches the expected env var name
- Regenerate the token in the DigitalOcean console if it was revoked/expired
- Verify client construction logs — fix the initialization error that left client nil
Example fix
// before (systemd unit, no env) ExecStart=/usr/local/bin/wtfutil // after ExecStart=/usr/local/bin/wtfutil Environment=DIGITALOCEAN_ACCESS_TOKEN=dop_v1_xxxx
Defensive patterns
Strategy: validation
Validate before calling
if os.Getenv("DIGITALOCEAN_ACCESS_TOKEN") == "" {
return errors.New("DIGITALOCEAN_ACCESS_TOKEN must be set")
} Type guard
func clientReady(w *Widget) bool { return w != nil && w.client != nil } Try / catch
if err := widget.Fetch(); err != nil {
if err.Error() == "client could not be initialized" {
log.Print("check DIGITALOCEAN_ACCESS_TOKEN and client setup")
return
}
return err
} Prevention
- Verify the token env var in the exact environment wtfutil launches from (systemd/launchd need Environment= lines)
- Log client-construction errors instead of silently leaving client nil
- Use a read-scoped personal access token
- Add a startup health check that calls Fetch once and reports the error
When it happens
Trigger: Widget loaded without an access token env var set; token rejected/empty at NewClient time so widget.client was never assigned; Fetch() or Refresh()/fetchAndDisplayEvents() invoked before successful client setup.
Common situations: DIGITALOCEAN_ACCESS_TOKEN missing from the environment wtfutil runs in (systemd/launchd don't inherit your shell env); expired or revoked API token; typo'd env var name in config.yml.
Related errors
- cannot store secrets: wtf.secretStore is not configured
- URL is not defined
- invalid URL: %w
- invalid status page URL format. Expected '.../status/<slug>'
- invalid app index selected
AI-assisted analysis of wtfutil/wtf@bb838c1ccb (2026-09-03).
Data as JSON: /api/errors/443885afaf6cd069.
Report an issue: GitHub.