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
- Read the wrapped cause (%w) at the end of the error for the exact field/decoding problem.
- Fix the field name or value type in document N indicated in the message.
- Check the docs for the specific source/tool to confirm supported fields and types.
- 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
- Diff YAML fields against the current version's source/tool docs on every toolbox upgrade.
- Use strict YAML linting with a schema per kind.
- Avoid guessing field names; copy from documented examples.
- Add a CI step that parses every config file before merge.
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
- error unmarshaling %s: %w
- doc %d: unexpected non-string key in input: %v
- doc %d: invalid config format at key %q: %w
- doc %d: invalid config format at key %q: expected nested for
- unable to parse YAML: %s
AI-assisted analysis of googleapis/mcp-toolbox@8cc6e09de2 (2026-09-05).
Data as JSON: /api/errors/0e4f8e15afb4b758.
Report an issue: GitHub.