googleapis/mcp-toolbox · error
unable to get logger from ctx: %s
Error message
unable to get logger from ctx: %s
What it means
vacuumTool.models retrieves the structured logger from the request context via util.LoggerFromContext(ctx). The MCP server normally injects a logger into the context before invoking a tool; if it is absent (or the stored value fails the type assertion to the expected logger type), the tool aborts the models vacuum step and returns this wrapped error. Without the logger the tool cannot emit progress events during vacuuming.
Source
Thrown at internal/tools/looker/lookerhealthvacuum/lookerhealthvacuum.go:207
}
// =================================================================================================================
// END MCP SERVER CORE LOGIC
// =================================================================================================================
// =================================================================================================================
// START LOOKER HEALTH VACUUM CORE LOGIC
// =================================================================================================================
type vacuumTool struct {
SdkClient *v4.LookerSDK
timeframe int
minQueries int
}
func (t *vacuumTool) models(ctx context.Context, project, model string) ([]map[string]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, "Vacuuming models...")
usedModels, err := t.getUsedModels(ctx)
if err != nil {
return nil, err
}
lookmlModels, err := t.SdkClient.AllLookmlModels(v4.RequestAllLookmlModels{}, nil)
if err != nil {
return nil, fmt.Errorf("error fetching LookML models: %w", err)
}
var results []map[string]interface{}
for _, m := range lookmlModels {
if (project == "" || (m.ProjectName != nil && *m.ProjectName == project)) &&
(model == "" || (m.Name != nil && *m.Name == model)) {
View on GitHub (pinned to 8cc6e09de2)
Solutions
- Call the tool through the normal MCP server Invoke path, which attaches the logger to the context.
- In tests, attach a logger first, e.g. ctx = util.WithLogger(ctx, logger) (or the project's helper) before invoking.
- If using custom middleware, ensure it derives from the incoming ctx rather than replacing it with context.Background().
Example fix
// before err := tool.Invoke(context.Background(), src, params, token) // after ctx := util.WithLogger(context.Background(), slog.Default()) err := tool.Invoke(ctx, src, params, token)
Defensive patterns
Strategy: validation
Validate before calling
if _, err := util.LoggerFromContext(ctx); err != nil {
ctx = util.WithLogger(ctx, slog.Default())
} Type guard
func ensureLogger(ctx context.Context) context.Context {
if _, err := util.LoggerFromContext(ctx); err != nil {
return util.WithLogger(ctx, slog.Default())
}
return ctx
} Try / catch
models, err := vt.models(ctx, project, model)
if err != nil {
if strings.Contains(err.Error(), "unable to get logger from ctx") {
ctx = util.WithLogger(ctx, slog.Default())
models, err = vt.models(ctx, project, model)
}
return err
} Prevention
- Never invoke tools with a bare context.Background(); always derive from the request context.
- In tests, use a helper that injects a logger into the context before every tool call.
- Avoid middleware that replaces the context wholesale; derive new contexts from the incoming one.
- Wrap tool invocation in a helper that guarantees logger injection.
When it happens
Trigger: Calling vacuumTool.models (directly in tests, or via Invoke) with a bare context.Context that never had a logger attached — e.g. context.Background() in unit tests, or a code path that strips context values before calling the tool.
Common situations: Unit/integration tests constructing the tool and calling Invoke with ctx := context.Background(); custom harnesses that rebuild the request context and drop the server-injected logger; middleware that replaces the context instead of adding to it.
Related errors
- 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
- failed to get logger from context: %w
AI-assisted analysis of googleapis/mcp-toolbox@8cc6e09de2 (2026-09-05).
Data as JSON: /api/errors/c4175188e28da335.
Report an issue: GitHub.