googleapis/mcp-toolbox · warning
unable to get logger from ctx: %s
Error message
unable to get logger from ctx: %s
What it means
checkDBConnections retrieves a structured logger from the request context via util.LoggerFromContext; if the context carries no logger it returns this error. The pulse checks rely on contextual logging, so a bare context.Background() without the server's logger injection will fail. It indicates the tool was invoked outside the server's normal request pipeline.
Source
Thrown at internal/tools/looker/lookerhealthpulse/lookerhealthpulse.go:210
return t.checkDashboardPerformance(ctx, source)
case "check_dashboard_errors":
return t.checkDashboardErrors(ctx, source)
case "check_explore_performance":
return t.checkExplorePerformance(ctx, source)
case "check_schedule_failures":
return t.checkScheduleFailures(ctx, source)
case "check_legacy_features":
return t.checkLegacyFeatures(ctx, source)
default:
return nil, fmt.Errorf("unknown action: %s", params.Action)
}
}
// Check DB connections and run tests
func (t *pulseTool) checkDBConnections(ctx context.Context, source compatibleSource) (interface{}, error) {
logger, err := util.LoggerFromContext(ctx)
if err != nil {
return nil, fmt.Errorf("unable to get logger from ctx: %s", err)
}
logger.InfoContext(ctx, "Test 1/6: Checking connections")
reservedNames := map[string]struct{}{
"looker__internal__analytics__replica": {},
"looker__internal__analytics": {},
"looker": {},
"looker__ilooker": {},
}
connections, err := t.SdkClient.AllConnections("", source.LookerApiSettings())
if err != nil {
return nil, fmt.Errorf("error fetching connections: %w", err)
}
var filteredConnections []v4.DBConnection
for _, c := range connections {
if _, reserved := reservedNames[*c.Name]; !reserved {View on GitHub (pinned to 8cc6e09de2)
Solutions
- Invoke the tool through the server's normal request path, which injects the logger into ctx.
- In tests or custom code, add a logger first: ctx = util.AddLoggerToContext(ctx, slog.Default()) (or the equivalent helper).
- Pass the request's context, not context.Background(), into Invoke.
- Check the util package for the exact logger context helper used by this version.
Example fix
// before t.Invoke(ctx, src, params, token) // ctx = context.Background() // after logger := slog.Default() ctx = util.AddLoggerToContext(context.Background(), logger) t.Invoke(ctx, src, params, token)
Defensive patterns
Strategy: try-catch
Validate before calling
if util.LoggerFromContext(ctx) == nil /* or err != nil via helper */ {
ctx = util.AddLoggerToContext(ctx, slog.Default())
} Try / catch
result, toolErr := tool.Invoke(ctx, src, params, token)
if toolErr != nil && strings.Contains(toolErr.Error(), "unable to get logger") {
ctx = util.AddLoggerToContext(ctx, slog.Default())
result, toolErr = tool.Invoke(ctx, src, params, token)
} Prevention
- Always invoke tools through the server request path that injects the logger
- In tests, build contexts with the util logger helper instead of context.Background()
- Preserve request context values in goroutines (pass ctx down, don't recreate it)
- Check util.LoggerFromContext behavior when upgrading server versions
When it happens
Trigger: Calling checkDBConnections (via RunPulse/Invoke) with a context that was not populated by util.AddLoggerToContext / the server's middleware, e.g. in custom harnesses, tests, or scripts.
Common situations: Custom test harnesses passing context.Background(), background goroutines that drop the request context, or older server versions that did not inject a logger.
Related errors
- unable to retrieve logger: %w
- unable to get logger from ctx: %s
- error getting logger from context in ExtractLookerFieldPrope
- unable to get logger from ctx: %s
- unable to get logger from ctx: %s
AI-assisted analysis of googleapis/mcp-toolbox@8cc6e09de2 (2026-09-05).
Data as JSON: /api/errors/ac439214b9ca0122.
Report an issue: GitHub.