googleapis/mcp-toolbox · error

unable to get logger from ctx: %s

Error message

unable to get logger from ctx: %s

What it means

Looker's Config.Initialize pulls a slog logger out of the context via util.LoggerFromContext; the toolbox always injects one at startup. If it is absent, Initialize cannot log and aborts with this error. This almost always means the source is being initialized outside the normal server bootstrap path (e.g. tests or custom embedding) without the logger context value.

Source

Thrown at internal/sources/looker/looker.go:94

	Timeout            string `yaml:"timeout"`
	ShowHiddenModels   bool   `yaml:"show_hidden_models"`
	ShowHiddenExplores bool   `yaml:"show_hidden_explores"`
	ShowHiddenFields   bool   `yaml:"show_hidden_fields"`
	Project            string `yaml:"project"`
	Location           string `yaml:"location"`
	QuotaProject       string `yaml:"quotaProject"`
	SessionLength      int64  `yaml:"sessionLength"`
}

func (r Config) SourceConfigType() string {
	return SourceType
}

// Initialize initializes a Looker Source instance.
func (r Config) Initialize(ctx context.Context, tracer trace.Tracer) (sources.Source, error) {
	logger, err := util.LoggerFromContext(ctx)
	if err != nil {
		return nil, fmt.Errorf("unable to get logger from ctx: %s", err)
	}

	userAgent, err := util.UserAgentFromContext(ctx)
	if err != nil {
		return nil, err
	}

	duration, err := time.ParseDuration(r.Timeout)
	if err != nil {
		return nil, fmt.Errorf("unable to parse Timeout string as time.Duration: %s", err)
	}

	if !r.SslVerification {
		logger.WarnContext(ctx, "Insecure HTTP is enabled for Looker source %s. TLS certificate verification is skipped.\n", r.Name)
	}
	cfg := rtl.ApiSettings{
		AgentTag:     userAgent,
		BaseUrl:      r.BaseURL,

View on GitHub (pinned to 8cc6e09de2)

Solutions

  1. Add the toolbox logger to the context before calling Initialize, e.g. util.AddLoggerToContext / the same helper the server uses.
  2. If in tests, use the context fixture the other source tests use (it already carries a logger).
  3. Ensure you initialize sources through the toolbox server bootstrap rather than calling Initialize directly with a raw context.

Example fix

// before
src, err := cfg.Initialize(context.Background(), tracer)
// after
logger := slog.Default()
ctx := util.AddLoggerToContext(context.Background(), logger)
src, err := cfg.Initialize(ctx, tracer)
Defensive patterns

Strategy: validation

Validate before calling

// Go: before calling Initialize directly, ensure the ctx carries the toolbox logger
if util.LoggerFromContext(ctx) != nil == false {
    ctx = util.AddLoggerToContext(ctx, slog.Default()) // or your configured logger
}

Try / catch

src, err := cfg.Initialize(ctx, tracer)
if err != nil {
    if strings.Contains(err.Error(), "unable to get logger from ctx") {
        // context wasn't prepared by the toolbox bootstrap; add logger and retry once
        ctx = util.AddLoggerToContext(ctx, slog.Default())
        src, err = cfg.Initialize(ctx, tracer)
    }
    if err != nil { return err }
}

Prevention

When it happens

Trigger: Calling Config.Initialize(ctx, tracer) with a bare context.Context that was not decorated by the toolbox's server setup (which normally adds the logger via context utilities).

Common situations: Unit/integration tests constructing sources manually with context.Background(); embedding the toolbox as a library without running its server initialization; a modified bootstrap path dropping the logger.

Related errors


AI-assisted analysis of googleapis/mcp-toolbox@8cc6e09de2 (2026-09-05). Data as JSON: /api/errors/4a5c5630d943b2c9. Report an issue: GitHub.