googleapis/mcp-toolbox · error

error getting logger from context in ExtractLookerFieldPrope

Error message

error getting logger from context in ExtractLookerFieldProperties: %v

What it means

ExtractLookerFieldProperties fetches the logger from the context via util.LoggerFromContext. If the context carries no logger, it cannot log field extraction progress, so it aborts and returns this error instead of an empty field map.

Source

Thrown at internal/tools/looker/lookercommon/lookercommon.go:50

	FiltersFields    = "fields(filters(name,type,label,label_short,description,synonyms,tags,hidden,suggestable,suggestions,suggest_dimension,suggest_explore))"
	MeasuresFields   = "fields(measures(name,type,label,label_short,description,synonyms,tags,hidden,suggestable,suggestions,suggest_dimension,suggest_explore))"
	ParametersFields = "fields(parameters(name,type,label,label_short,description,synonyms,tags,hidden,suggestable,suggestions,suggest_dimension,suggest_explore))"
)

// ExtractLookerFieldProperties extracts common properties from Looker field objects.
func ExtractLookerFieldProperties(ctx context.Context, fields *[]v4.LookmlModelExploreField, showHiddenFields bool) ([]any, error) {
	data := make([]any, 0)

	// Handle nil fields pointer
	if fields == nil {
		return data, nil
	}

	logger, err := util.LoggerFromContext(ctx)
	if err != nil {
		// This should ideally not happen if the context is properly set up.
		// Log and return an empty map or handle as appropriate for your error strategy.
		return data, fmt.Errorf("error getting logger from context in ExtractLookerFieldProperties: %v", err)
	}

	for _, v := range *fields {
		logger.DebugContext(ctx, "Got response element of %v\n", v)
		if v.Name != nil && strings.HasSuffix(*v.Name, "_raw") {
			continue
		}
		if !showHiddenFields && v.Hidden != nil && *v.Hidden {
			continue
		}
		vMap := make(map[string]any)
		if v.Name != nil {
			vMap["name"] = *v.Name
		}
		if v.Type != nil {
			vMap["type"] = *v.Type
		}
		if v.Label != nil {

View on GitHub (pinned to 8cc6e09de2)

Solutions

  1. Use the request context propagated by the toolbox server, which embeds the logger.
  2. In tests or standalone code, attach a logger first: ctx := util.ContextWithLogger(ctx, logger).
  3. If spawning goroutines, pass the parent (logger-carrying) context or re-attach the logger.

Example fix

// before
fields, err := lookercommon.ExtractLookerFieldProperties(context.Background(), resp)
// after
logger := slog.Default()
ctx := util.ContextWithLogger(context.Background(), logger)
fields, err := lookercommon.ExtractLookerFieldProperties(ctx, resp)
Defensive patterns

Strategy: validation

Validate before calling

// Ensure a logger is present before calling
if _, err := util.LoggerFromContext(ctx); err != nil {
    ctx = util.ContextWithLogger(ctx, slog.Default())
}

Try / catch

fields, err := lookercommon.ExtractLookerFieldProperties(ctx, resp)
if err != nil && strings.Contains(err.Error(), "error getting logger") {
    ctx = util.ContextWithLogger(ctx, slog.Default())
    fields, err = lookercommon.ExtractLookerFieldProperties(ctx, resp)
}

Prevention

When it happens

Trigger: Calling ExtractLookerFieldProperties with a ctx that never had a logger attached (e.g., a raw context.Background() in tests or a code path bypassing the server's context middleware).

Common situations: Unit tests calling the helper directly with a bare context; custom invoke wrappers dropping the logger middleware; background goroutines spawned with a new context.

Related errors


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