googleapis/mcp-toolbox · error
error unmarshaling %s: %w
Error message
error unmarshaling %s: %w
What it means
Single-document variant of the unmarshaling failure: when the YAML file contains only one document, UnmarshalPrimitiveConfig returns 'error unmarshaling <kind>: <cause>' without document-index decoration. The wrapped cause from UnmarshalYAMLSourceConfig / UnmarshalYAMLToolConfig / etc. holds the actual decoding error.
Source
Thrown at internal/server/config.go:238
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)
}
if authServiceConfigs == nil {
authServiceConfigs = make(AuthServiceConfigs)View on GitHub (pinned to 8cc6e09de2)
Solutions
- Inspect the wrapped cause after the colon for the exact offending field.
- Correct the key spelling or value type in the YAML.
- Validate against the documented schema for that kind.
- Upgrade/downgrade alignment: check release notes for schema changes to that kind.
Example fix
// before kind: tool name: t source: mysource description: 42 // after kind: tool name: t source: mysource description: my tool
Defensive patterns
Strategy: validation
Validate before calling
var probe map[string]any
if err := yaml.Unmarshal([]byte(cfgText), &probe); err != nil { return err }
// ensure every key maps to the documented type before handing to ParseConfig
for field, v := range probe {
_ = field
_ = v
}
// then run the real parse to catch strict-unmarshal issues early
if _, _, _, _, _, _, err := server.ParseConfig(ctx, params); err != nil {
return fmt.Errorf("config parse failed: %w", err)
}
return nil Try / catch
if err := parseAndValidate(cfgText); err != nil {
cause := err
for errors.Unwrap(cause) != nil { cause = errors.Unwrap(cause) }
log.Fatalf("single-doc unmarshal failure — fix the root cause: %v", cause)
} Prevention
- Pin the toolbox version and re-validate configs after upgrades.
- Keep one kind per file when using single-document configs.
- Check for typos with a YAML schema validator.
- Quote ambiguous scalar values.
When it happens
Trigger: ParseConfig on a single-document YAML whose resource map fails strict decoding into the config struct for its kind (unknown fields, wrong value types, invalid nested configs).
Common situations: Typo'd keys in a standalone tools.yaml; passing a string where a list is expected; using a prebuilt-config field that no longer exists after upgrade.
Related errors
- document %d: error unmarshaling %s %q: %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/cec85786cd827314.
Report an issue: GitHub.