{"record":{"id":"1b38ed50bee4842a","repo":"googleapis/mcp-toolbox","slug":"failed-to-marshal-to-json-w","errorCode":null,"errorMessage":"failed to marshal to JSON: %w","messagePattern":"failed to marshal to JSON: %w","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/tools/serverlessspark/createbatch/config.go","lineNumber":33,"sourceCode":"package createbatch\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"fmt\"\n\n\tdataprocpb \"cloud.google.com/go/dataproc/v2/apiv1/dataprocpb\"\n\t\"github.com/goccy/go-yaml\"\n\t\"github.com/googleapis/mcp-toolbox/internal/tools\"\n\t\"google.golang.org/protobuf/encoding/protojson\"\n\t\"google.golang.org/protobuf/proto\"\n)\n\n// unmarshalProto is a helper function to unmarshal a generic interface{} into a proto.Message.\nfunc unmarshalProto(data any, m proto.Message) error {\n\tjsonData, err := json.Marshal(data)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to marshal to JSON: %w\", err)\n\t}\n\treturn protojson.Unmarshal(jsonData, m)\n}\n\ntype compatibleSource interface {\n\tCreateBatch(context.Context, *dataprocpb.Batch) (map[string]any, error)\n}\n\n// Config is a common config that can be used with any type of create batch tool. However, each tool\n// will still need its own config type, embedding this Config, so it can provide a type-specific\n// Initialize implementation.\ntype Config struct {\n\ttools.ConfigBase  `yaml:\",inline\"`\n\tType              string                        `yaml:\"type\" validate:\"required\"`\n\tSource            string                        `yaml:\"source\" validate:\"required\"`\n\tRuntimeConfig     *dataprocpb.RuntimeConfig     `yaml:\"runtimeConfig\"`\n\tEnvironmentConfig *dataprocpb.EnvironmentConfig `yaml:\"environmentConfig\"`\n}","sourceCodeStart":15,"sourceCodeEnd":51,"githubUrl":"https://github.com/googleapis/mcp-toolbox/blob/8cc6e09de2ad7b8bffc77751799585a1401a48eb/internal/tools/serverlessspark/createbatch/config.go#L15-L51","documentation":"unmarshalProto first json.Marshal's the generic config value (parsed from YAML) before feeding it to protojson.Unmarshal. This error means the marshal step itself failed, which is rare and indicates the value contains a type the standard JSON encoder cannot serialize (e.g. channel, func, or a malformed structure) rather than a schema mismatch.","triggerScenarios":"NewConfig calls unmarshalProto with a decoded YAML value for RuntimeConfig or EnvironmentConfig whose underlying data cannot be marshaled by encoding/json (e.g. contains non-serializable Go values injected programmatically).","commonSituations":"Constructing Config programmatically (not via YAML) and passing unsupported types in RuntimeConfig/EnvironmentConfig; custom YAML decoders producing exotic types.","solutions":["Inspect the wrapped error after 'failed to marshal to JSON:' to see the offending type","Ensure RuntimeConfig/EnvironmentConfig values come from standard YAML/JSON decoding (maps, slices, scalars)","If building Config in Go, use JSON-serializable structures or protojson-native types"],"exampleFix":"// before\nrc := map[string]any{\"properties\": make(chan int)}\ncfg.RuntimeConfig, _ = unmarshalToProto(rc)\n// after\nrc := map[string]any{\"properties\": map[string]any{\"key\": \"value\"}}","handlingStrategy":"validation","validationCode":"// Ensure the value is JSON-encodable before handing to NewConfig\nif _, err := json.Marshal(runtimeConfigRaw); err != nil {\n    return fmt.Errorf(\"runtimeConfig is not JSON-encodable: %w\", err)\n}","typeGuard":"func isJSONEncodable(v any) bool { _, err := json.Marshal(v); return err == nil }","tryCatchPattern":"cfg, err := NewConfig(ctx, raw)\nif err != nil && strings.Contains(err.Error(), \"failed to marshal to JSON\") {\n    log.Fatalf(\"runtimeConfig/environmentConfig contains non-serializable data: %v\", err)\n}","preventionTips":["Only feed standard YAML/JSON-decoded values into NewConfig","Avoid passing Go-native types (channels, funcs) into proto config helpers","Round-trip programmatic config values through json.Marshal/Unmarshal to normalize them"],"tags":["json","protobuf","serialization","serverlessspark"],"backgroundTag":"json-marshal-failed","analyzedSha":"8cc6e09de2ad7b8bffc77751799585a1401a48eb","analyzedAt":"2026-09-05T01:10:36.887Z","contentChangedAt":"2026-09-05T01:10:36.887Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}