matryer/xbar · error
unsupported action %q
Error message
unsupported action %q
What it means
After the scheme check, parseIncomingURL extracts the action from the URL path and dispatches only on the three known actions: openPlugin, refreshPlugin, refreshAllPlugins. Anything else (empty path, typo, new/renamed action) falls to the default branch and is rejected with the offending action quoted, preventing arbitrary path traversal through the handler.
Source
Thrown at app/incoming_urls.go:34
// parseIncomingURL parses an incoming xbar:// URL.
func parseIncomingURL(urlStr string) (incomingURL, error) {
var inURL incomingURL
u, err := url.Parse(urlStr)
if err != nil {
return inURL, err
}
if u.Scheme != "xbar" && u.Host != "app.xbarapp.com" {
return inURL, errors.New("not an xbar:// url")
}
inURL.Action = strings.Trim(u.Path, "/")
inURL.Params = u.Query()
switch inURL.Action {
case "openPlugin":
case "refreshPlugin":
case "refreshAllPlugins":
default: // not ok
return inURL, errors.Errorf("unsupported action %q", inURL.Action)
}
return inURL, nil
}
View on GitHub (pinned to d624239058)
Solutions
- Use one of the supported actions exactly: openPlugin, refreshPlugin, refreshAllPlugins
- Include a non-empty path in the URL, e.g. xbar://refreshPlugin?path=/users/me/cpu.5s.sh
- Match the case exactly — actions are lowercase
- Check the app version supports the action you're linking to and update the link or app
Example fix
// before
parseIncomingURL("xbar://refresh-plugins?path=/cpu.5s.sh")
// after
parseIncomingURL("xbar://refreshPlugin?path=/cpu.5s.sh") Defensive patterns
Strategy: validation
Validate before calling
var validActions = map[string]bool{"openPlugin": true, "refreshPlugin": true, "refreshAllPlugins": true}
func hasKnownAction(raw string) bool {
u, err := url.Parse(raw)
if err != nil {
return false
}
return validActions[strings.Trim(u.Path, "/")]
} Type guard
func isSupportedAction(action string) bool {
return action == "openPlugin" || action == "refreshPlugin" || action == "refreshAllPlugins"
} Try / catch
inURL, err := parseIncomingURL(raw)
if err != nil {
var unsupported string
if _, scan := fmt.Sscanf(err.Error(), "unsupported action %q", &unsupported); scan == nil {
log.Printf("unknown deep-link action %q, ignoring", unsupported)
return
}
return err
} Prevention
- Centralize deep-link construction in one helper that only emits the three known actions
- Keep action names lowercase and exact
- Never build links from untrusted path input without whitelisting the action
- Add a table-driven test enumerating all supported actions
When it happens
Trigger: parseIncomingURL called with a valid xbar:// URL whose trimmed path is not one of the three supported actions, e.g. xbar://openPlugins (typo), xbar:// (empty path), or xbar://installPlugin?path=... (unsupported action).
Common situations: Typos in action names when constructing deep links programmatically; forgetting the path entirely (xbar://?path=...); copying an action name from a newer or older app version where the action set differs; case sensitivity mistakes (OpenPlugin).
Related errors
- not an xbar:// url
- malformed xbar.var format
- malformed xbar.var format (missing select options)
- malformed xbar.var format (empty select options)
- disabled
AI-assisted analysis of matryer/xbar@d624239058 (2026-09-02).
Data as JSON: /api/errors/187a5c240c4d6e93.
Report an issue: GitHub.