kataras/iris · error
client.Do: default request option[%d]: %w
Error message
client.Do: default request option[%d]: %w
What it means
Client.Do wraps any error returned by one of the client's PersistentRequestOptions (default request option functions) with this message, including the option's index in the slice and the original error via %w. These options are applied to every outgoing request before the per-call custom options, so if one fails the request is never sent. It is a configuration-time bug in a registered default option, not a network or server problem.
Source
Thrown at x/client/client.go:265
if c.BaseURL != "" {
urlpath = c.BaseURL + urlpath // note that we don't do any special checks here, the caller is responsible.
}
// Initialize the request.
req, err := http.NewRequestWithContext(ctx, method, urlpath, body)
if err != nil {
return nil, err
}
// We separate the error for the default options for now.
for i, opt := range c.PersistentRequestOptions {
if opt == nil {
continue
}
if err = opt(req); err != nil {
return nil, fmt.Errorf("client.Do: default request option[%d]: %w", i, err)
}
}
// Apply any custom request options (e.g. content type, accept headers, query...)
for _, opt := range opts {
if opt == nil {
continue
}
if err = opt(req); err != nil {
return nil, err
}
}
if err = c.emitBeginRequest(ctx, req); err != nil {
return nil, err
}
View on GitHub (pinned to 7bedaf55a0)
Solutions
- Read the [%d] index in the message and inspect the corresponding function in c.PersistentRequestOptions; fix or guard the code inside that option so it returns nil on the happy path.
- Validate the option's inputs (token, header value, URL) when constructing the Client rather than at request time, returning an error once at startup.
- If the option should be optional, make it skip gracefully (return nil) when its prerequisites are missing instead of erroring per request.
- Check recent changes to PersistentRequestOptions registration (env vars, secrets, config loading) that could make the option fail.
- Unwrap the error (errors.Unwrap / errors.As) to see the root cause returned by the failing option.
Example fix
// before: fails at request time when token is missing
client.PersistentRequestOptions = append(client.PersistentRequestOptions, func(r *http.Request) error {
tok := os.Getenv("API_TOKEN")
if tok == "" { return errors.New("empty token") }
r.Header.Set("Authorization", "Bearer "+tok)
return nil
})
// after: validate once at client construction
if os.Getenv("API_TOKEN") == "" { return nil, errors.New("API_TOKEN required") }
client.PersistentRequestOptions = append(client.PersistentRequestOptions, func(r *http.Request) error {
r.Header.Set("Authorization", "Bearer "+os.Getenv("API_TOKEN"))
return nil
}) Defensive patterns
Strategy: validation
Validate before calling
for i, opt := range client.PersistentRequestOptions {
if opt == nil { continue }
probe, _ := http.NewRequest(http.MethodGet, "https://example.invalid/", nil)
if err := opt(probe); err != nil {
return fmt.Errorf("persistent request option[%d] invalid: %w", i, err)
}
}
// run once at client construction/startup Try / catch
var optErr *RequestOptionError
if err := client.ReadJSON(ctx, &dest, method, path, nil); err != nil {
if strings.Contains(err.Error(), "default request option[") && errors.As(err, &optErr) {
// fix/rebuild client config, do not retry blindly
}
} Prevention
- Validate all inputs a persistent option needs (tokens, headers, base URL) once at client construction, not per request.
- Keep PersistentRequestOptions minimal and side-effect free; prefer pure header setters.
- Never register an option factory that can return an error-producing option without testing it at startup.
- Log the option index from the error message to pinpoint the failing registration quickly.
When it happens
Trigger: Any call to Client.Do, JSON, Form, ReadJSON, ReadPlain or WriteTo when an entry in c.PersistentRequestOptions returns a non-nil error while mutating the http.Request (e.g. a persistent auth-header option that fails to resolve a token, a base-path rewriter hitting an invalid URL, or a malformed persistent header value). The index in the message identifies which registered option failed.
Common situations: Registering PersistentRequestOptions on the Client (often at app init) with an option that depends on external state — an empty/expired API token, a context value that is absent when Do runs, a URL path that breaks after BaseURL concatenation, or a factory function that built an invalid option. Frequently surfaces after config or env changes (missing env var for a token provider).
Related errors
- auth: configuration: %s access token is missing from the con
- %w: example: %s
- parse yaml: %w
- nil loader
- catalog: empty languages
AI-assisted analysis of kataras/iris@7bedaf55a0 (2026-08-30).
Data as JSON: /api/errors/88bcd0e1a1ac537c.
Report an issue: GitHub.