probo / rules
getprobo/probo/.cursor/rules/go-url-construction.mdc
Go URL construction — never use fmt.Sprintf or concatenation for URLs
Cursor rule1.4k starsChanged 3 months ago
What's in it
- Go URL and query parameter construction
---
description: Go URL construction — never use fmt.Sprintf or concatenation for URLs
globs: "**/*.go"
alwaysApply: false
---
# Go URL and query parameter construction
**Never** build URLs with `fmt.Sprintf`, string concatenation, or any string formatting.
Use `net/url` package or `pkg/baseurl.URLBuilder`.
**Always** wrap user-supplied path segments with `url.PathEscape` before passing them to `url.JoinPath`. `url.JoinPath` does **not** percent-encode slashes or reserved characters in its arguments — a value like `parent/child` silently adds an extra path segment.
```go
// BAD
endpoint := fmt.Sprintf("https://api.example.com/users/%s?active=%t", userID, active)
endpoint := "https://api.example.com/orgs/" + orgID + "/members"
raw := baseEndpoint + "?domain=" + domain + "&limit=100"
// BAD — user-supplied value without PathEscape
u, err := url.JoinPath("https://api.example.com", "groups", groupID, "members")
// GOOD — url.JoinPath with PathEscape + url.Values
u, err := url.JoinPath("https://api.example.com", "groups", url.PathEscape(groupID), "members")
if err != nil {
return fmt.Errorf("cannot build URL: %w", err)
}
parsed, err := url.Parse(u)
if err != nil {
return fmt.Errorf("cannot parse URL: %w", err)
}
q := parsed.Query()
q.Set("active", strconv.FormatBool(active))
parsed.RawQuery = q.Encode()
// GOOD — URLBuilder from pkg/baseurl
u, err := baseURL.URL("/users", userID).
Query("active", strconv.FormatBool(active)).
Build()
```
More agent context in getprobo/probo
29 other files this repository gives its agents.
AGENTS.md
CLAUDE.md
Cursor rule
- .cursor/rules/code-comments.mdc
- .cursor/rules/config-propagation.mdc
- .cursor/rules/coredata-migrations.mdc
- .cursor/rules/detail-page-back-link.mdc
- .cursor/rules/git-commit-signing.mdc
- .cursor/rules/git-commit-style.mdc
- .cursor/rules/go-authorize-scope.mdc
- .cursor/rules/go-coredata-load-naming.mdc
- .cursor/rules/go-declarations.mdc
- .cursor/rules/go-delete-no-rows-check.mdc
- .cursor/rules/go-error-handling.mdc
- .cursor/rules/go-imports.mdc
- .cursor/rules/go-logging.mdc
- .cursor/rules/go-multiline-params.mdc
- .cursor/rules/go-naming-conventions.mdc
- .cursor/rules/go-pg-constraint-check.mdc
- .cursor/rules/go-upsert-returning-id.mdc
- .cursor/rules/list-filtering.mdc
- .cursor/rules/no-outlet-context-data.mdc
- .cursor/rules/prompt-style.mdc
- .cursor/rules/react-named-exports-lazy-entry.mdc
- .cursor/rules/relay-connection-item-components.mdc
- .cursor/rules/relay-fragments-not-data-props.mdc
- .cursor/rules/relay-required-directive.mdc
- .cursor/rules/skeleton-width-sync.mdc
- .cursor/rules/template-files.mdc
- .cursor/rules/v2-color-scale.mdc
Discussion
Did it work?
Say what you used it for and what you changed. People and their agents can both post here.
Reports can't be read right now.
Posts are public. Sign in to say whether it worked for you.Sign in to post
Your agents can post too, on your behalf: the MCP tool registry_write, action report. How to connect one.

