CORS Issues
Try-It Console Returns CORS Errors
Symptom: The try-it console shows CORS error or Failed to fetch when making requests.
Cause: Your API server doesn't include the correct CORS headers, or the browser blocks cross-origin requests from the docs UI to your API.
Solution: Configure CORS on your API server to allow requests from the docs origin:
import "github.com/rs/cors"
c := cors.New(cors.Options{
AllowedOrigins: []string{"https://docs.example.com"},
AllowedMethods: []string{"GET", "POST", "PUT", "DELETE", "OPTIONS"},
AllowedHeaders: []string{"Authorization", "Content-Type"},
AllowCredentials: true,
})
handler := c.Handler(router)Alternatively, configure a CORS proxy in the UI config:
docs := openswag.New(openswag.Config{
Title: "My API",
Version: "1.0.0",
UIConfig: openswag.UIConfig{
CORSProxyURL: "https://cors-proxy.internal.example.com",
},
})Spec Generation Failures
Spec Generation Panics on Nil Pointer
Symptom: panic: runtime error: invalid memory address or nil pointer dereference when generating the spec.
Cause: An endpoint has a nil Response or RequestBody field that the generator tries to dereference.
Solution: Ensure all required fields are set on your endpoints:
docs.AddEndpoint(openswag.Endpoint{
Method: "GET",
Path: "/api/users",
Summary: "List users",
Response: openswag.Response{
Status: 200,
Description: "Success", // Don't leave this empty
Body: openswag.BodyFrom[[]User](),
},
})Struct Fields Not Appearing in Schema
Symptom: Some struct fields are missing from the generated OpenAPI schema.
Cause: Fields without a json struct tag or unexported fields are skipped by the schema generator. In v1.0.x, embedded (anonymous) struct fields were also silently ignored.
Solution: Add json tags to all fields you want in the schema. For embedded structs, upgrade to v1.1.0+ where field promotion is supported:
// Bad — Name is exported but has no json tag, ID is unexported
type User struct {
id string
Name string
}
// Good
type User struct {
ID string `json:"id"`
Name string `json:"name"`
}
// Good (v1.1.0+) — embedded fields are promoted
type Timestamps struct {
CreatedAt time.Time `json:"created_at"`
}
type User struct {
Timestamps
ID string `json:"id"`
Name string `json:"name"`
}Example Values Have Wrong Type in Spec
Symptom: Example values like example:"42" appear as strings "42" instead of integers in the OpenAPI spec.
Cause: In v1.0.x, example tag values were always stored as strings regardless of the field type.
Solution: Upgrade to v1.1.0+. The ConvertExampleToType function now automatically coerces example strings to the correct type (int64, float64, bool, etc.) based on the field's Go type.
Map Fields Show as Empty Object
Symptom: map[string]T fields generate {"type":"object"} without additionalProperties.
Cause: In v1.0.x, map value schemas were not generated.
Solution: Upgrade to v1.1.0+. Map types now correctly produce {"type":"object","additionalProperties":{...}} with the value type's schema.
interface/any Fields Show as Object Type
Symptom: Fields typed as interface{} or any generate {"type":"object"} instead of accepting any value.
Cause: In v1.0.x, interface{}/any types were incorrectly mapped to {"type":"object"}.
Solution: Upgrade to v1.1.0+. These types now produce an empty schema {} which correctly accepts any JSON value.
Localhost Server URL Shows Garbled Characters
Symptom: Using CommonServers.Localhost(8080) produces a URL with garbled characters instead of the port number.
Cause: In v1.0.x, port numbers were converted using string(rune(port)) which produces a Unicode character instead of the decimal string.
Solution: Upgrade to v1.1.0+ where port conversion uses strconv.Itoa(port) correctly.
Circular Reference in Schema
Symptom: maximum recursion depth exceeded or the spec generation hangs.
Cause: Your Go structs have circular references (e.g., User has a field of type *User).
Solution: Use pointer types for self-referencing fields. The schema generator handles *T by generating a $ref instead of inlining:
type TreeNode struct {
Value string `json:"value"`
Children []*TreeNode `json:"children,omitempty"`
}Framework Mounting Problems
Chi: 404 on All Doc Routes
Symptom: Mounting with Chi returns 404 for /docs, /docs/openapi.json, etc.
Cause: Missing trailing wildcard in the route pattern.
Solution: Use the adapter's Mount function instead of manual mounting:
// Bad
r.Handle("/docs", docs.Handler())
// Good
import chiadapter "github.com/gopackx/open-swag-go/adapters/chi"
chiadapter.Mount(r, "/docs", docs)Gin: Conflicting Route Handlers
Symptom: panic: handlers are already registered for this path when mounting docs.
Cause: Another route conflicts with the docs wildcard route.
Solution: Use MountGroup to mount docs under a route group:
import ginadapter "github.com/gopackx/open-swag-go/adapters/gin"
api := r.Group("/api")
ginadapter.MountGroup(api, "/docs", docs)Fiber: Docs Page Loads But UI Is Blank
Symptom: The docs path returns HTML but the Scalar UI doesn't render.
Cause: Fiber's default content type handling may interfere with static asset serving.
Solution: Ensure the Fiber adapter is mounted correctly and static assets are served with proper MIME types:
import fiberadapter "github.com/gopackx/open-swag-go/adapters/fiber"
fiberadapter.Mount(app, "/docs", docs)If the issue persists, check that no middleware is modifying response headers for the /docs path.
Echo: Middleware Blocking Doc Routes
Symptom: Docs routes return 401 or 403 due to auth middleware.
Cause: Global auth middleware applies to the docs routes.
Solution: Mount docs before applying auth middleware, or use a group without the middleware:
import echoadapter "github.com/gopackx/open-swag-go/adapters/echo"
// Mount docs first (no auth)
echoadapter.Mount(e, "/docs", docs)
// Then apply auth middleware to API routes
api := e.Group("/api", authMiddleware)General Issues
Docs Work Locally But Not in Production
Symptom: Everything works on localhost but the docs page is blank or returns errors in production.
Cause: Common causes include reverse proxy stripping paths, missing environment variables, or HTTPS/HTTP mismatch.
Solution:
- Check that your reverse proxy forwards the full path (including
/docs/openapi.json) - Verify environment variables for
DocsAuthcredentials are set - Ensure the
ServerURL in your config matches the production URL:
docs := openswag.New(openswag.Config{
Info: openswag.Info{
Title: "My API",
Version: "1.0.0",
},
Servers: []openswag.Server{
{URL: "https://api.example.com", Description: "Production"},
},
})