Troubleshooting
Common issues when using sentinel and how to resolve them.
Panic on Inspect or Scan
Symptom: panic: sentinel: type must be a struct
Cause: You passed a non-struct type to Inspect[T]() or Scan[T]().
Solution: Use the Try variants which return an error instead of panicking:
metadata, err := sentinel.TryInspect[MyType]()
if err != nil {
// Handle non-struct type
}
Custom Tags Not Appearing
Symptom: Your custom tag is missing from field.Tags.
Cause: Tags were registered after the type was already extracted and cached.
Solution: Register tags before the first Inspect or Scan call:
// Do this first
sentinel.Tag("custom")
// Then extract
metadata := sentinel.Inspect[User]()
If the type is already cached, the original extraction (without your tag) will be returned. In tests, use sentineltest.ResetCache(t) to clear the cache.
Types Not Discovered by Scan
Symptom: Related types are missing from the cache after Scan.
Cause: The types are outside your module boundary.
Solution: Scan only recurses into types within your module (determined by go.mod). Types from external packages are recorded as relationships but not extracted.
// Your module: github.com/you/app
type User struct {
Profile Profile // ✓ Extracted (same module)
Created time.Time // ✗ Not extracted (stdlib)
NullName sql.NullString // ✗ Not extracted (external)
}
If you need metadata for external types, use Inspect explicitly:
sentinel.Inspect[sql.NullString]()
Scan Not Recursing
Symptom: Scan behaves like Inspect—only the root type is cached.
Cause: Module path detection failed. This happens when debug.ReadBuildInfo() returns no data.
When this occurs:
- Running with
go runoutside a module - Some build configurations that strip debug info
Solution: Ensure you're running within a Go module context, or use Inspect explicitly for each type you need.
Unexported Fields Missing
Symptom: Some struct fields don't appear in metadata.Fields.
Cause: Only exported fields (uppercase names) are included. Go's reflection cannot access unexported fields from outside their package.
type User struct {
ID string // ✓ Included
name string // ✗ Not included (unexported)
}
Solution: This is expected behaviour. Export fields you need metadata for.
Stale Cache in Tests
Symptom: Test assertions fail because metadata reflects a previous extraction.
Cause: Sentinel's cache persists across tests.
Solution: Use the testing helpers with -tags testing:
func TestSomething(t *testing.T) {
sentineltest.ResetCache(t)
// Fresh extraction
}
Run with: go test -tags testing ./...
Next Steps
- Testing — test isolation patterns
- Scanning — module boundary details
- API Reference — TryInspect and TryScan documentation