googleapis/mcp-toolbox · error

document %d: error unmarshaling %s %q: %w

Error message

document %d: error unmarshaling %s %q: %w

What it means

After kind/name validation, UnmarshalPrimitiveConfig dispatches each document to a type-specific unmarshaler (e.g. UnmarshalYAMLSourceConfig). This error wraps the underlying unmarshaler failure with the document index, kind, and name. The %w-wrapped cause carries the real problem (unknown kind variant, bad field types, strict-mode unknown fields).

Source

Thrown at internal/server/config.go:236

		if !ok {
			if len(file.Docs) > 1 {
				fallbackToken := keyToken(doc.Body, "name")
				if fallbackToken == nil {
					fallbackToken = keyToken(doc.Body, "kind")
				}
				return nil, nil, nil, nil, nil, nil, fmt.Errorf("%s missing 'name' field or it is not a string", formatDocLocation(docIndex, fallbackToken, doc.Body))
			}
			return nil, nil, nil, nil, nil, nil, fmt.Errorf("missing 'name' field or it is not a string")
		}
		// remove 'kind' from map for strict unmarshaling
		delete(resource, "kind")

		switch kind {
		case "source":
			c, err := UnmarshalYAMLSourceConfig(ctx, name, resource)
			if err != nil {
				if len(file.Docs) > 1 {
					return nil, nil, nil, nil, nil, nil, fmt.Errorf("document %d: error unmarshaling %s %q: %w", docIndex, kind, name, err)
				}
				return nil, nil, nil, nil, nil, nil, fmt.Errorf("error unmarshaling %s: %w", kind, err)
			}
			if sourceConfigs == nil {
				sourceConfigs = make(SourceConfigs)
			}
			if _, exists := sourceConfigs[name]; exists {
				return nil, nil, nil, nil, nil, nil, fmt.Errorf("source %q declared more than once", name)
			}
			sourceConfigs[name] = c
		case "authService":
			c, err := UnmarshalYAMLAuthServiceConfig(ctx, name, resource)
			if err != nil {
				if len(file.Docs) > 1 {
					return nil, nil, nil, nil, nil, nil, fmt.Errorf("document %d: error unmarshaling %s %q: %w", docIndex, kind, name, err)
				}
				return nil, nil, nil, nil, nil, nil, fmt.Errorf("error unmarshaling %s: %w", kind, err)
			}

View on GitHub (pinned to 8cc6e09de2)

Solutions

  1. Read the wrapped cause (%w) at the end of the error for the exact field/decoding problem.
  2. Fix the field name or value type in document N indicated in the message.
  3. Check the docs for the specific source/tool to confirm supported fields and types.
  4. If a field was removed in a toolbox upgrade, migrate the config to the new schema.

Example fix

// before
kind: postgres
name: db
prot: 5432
// after
kind: postgres
name: db
port: 5432
Defensive patterns

Strategy: validation

Validate before calling

// Parse a draft config and surface the wrapped cause before deploying
cfg, _, _, _, _, _, err := server.ParseConfig(ctx, params)
if err != nil {
    var inner error
    for e := err; e != nil; e = errors.Unwrap(e) { inner = e }
    return fmt.Errorf("config invalid (see cause): %w", inner)
}

Try / catch

if _, err := server.ParseConfig(ctx, params); err != nil {
    var docErr = err
    for errors.Unwrap(docErr) != nil { docErr = errors.Unwrap(docErr) }
    log.Fatalf("YAML unmarshal failed at the indicated document: root=%v cause=%v", err, docErr)
}

Prevention

When it happens

Trigger: ParseConfig on a multi-document YAML file where document N's resource map fails strict YAML decoding into the config struct for its kind (e.g. a source with an invalid 'kind' subtype like kind: postgres with unknown/mistyped fields).

Common situations: Typos in source/tool parameter names; wrong types (host as integer); unsupported source kind inside the doc; schema drift after a toolbox version upgrade removed or renamed a field.

Related errors


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