{"record":{"id":"bc6e034a3aad5f56","repo":"router-for-me/CLIProxyAPI","slug":"invalid-generated-yaml-structure","errorCode":null,"errorMessage":"invalid generated yaml structure","messagePattern":"invalid generated yaml structure","errorType":"http","errorClass":null,"httpStatus":500,"severity":"error","filePath":"internal/config/config_yaml.go","lineNumber":43,"sourceCode":"\t}\n\tif original.Kind != yaml.DocumentNode || len(original.Content) == 0 {\n\t\treturn fmt.Errorf(\"invalid yaml document structure\")\n\t}\n\tif original.Content[0] == nil || original.Content[0].Kind != yaml.MappingNode {\n\t\treturn fmt.Errorf(\"expected root mapping node\")\n\t}\n\n\t// Marshal the current cfg to YAML, then unmarshal to a yaml.Node we can merge from.\n\trendered, err := yaml.Marshal(persistCfg)\n\tif err != nil {\n\t\treturn err\n\t}\n\tvar generated yaml.Node\n\tif err = yaml.Unmarshal(rendered, &generated); err != nil {\n\t\treturn err\n\t}\n\tif generated.Kind != yaml.DocumentNode || len(generated.Content) == 0 || generated.Content[0] == nil {\n\t\treturn fmt.Errorf(\"invalid generated yaml structure\")\n\t}\n\tif generated.Content[0].Kind != yaml.MappingNode {\n\t\treturn fmt.Errorf(\"expected generated root mapping node\")\n\t}\n\n\t// Remove deprecated sections before merging back the sanitized config.\n\tremoveLegacyAuthBlock(original.Content[0])\n\tremoveLegacyOpenAICompatAPIKeys(original.Content[0])\n\tremoveRemovedIntegrationKeys(original.Content[0])\n\tremoveLegacyGenerativeLanguageKeys(original.Content[0])\n\n\tpruneMappingToGeneratedKeys(original.Content[0], generated.Content[0], \"oauth-excluded-models\")\n\tpruneMappingToGeneratedKeys(original.Content[0], generated.Content[0], \"oauth-model-alias\")\n\tpruneMappingToGeneratedKeys(original.Content[0], generated.Content[0], \"plugins\", \"configs\")\n\n\t// Merge generated into original in-place, preserving comments/order of existing nodes.\n\tmergeMappingPreserve(original.Content[0], generated.Content[0])\n\tnormalizeCollectionNodeStyles(original.Content[0])","sourceCodeStart":25,"sourceCodeEnd":61,"githubUrl":"https://github.com/router-for-me/CLIProxyAPI/blob/78f0c4079e3e6273d65d03b5549cffc898703264/internal/config/config_yaml.go#L25-L61","documentation":"Thrown when the config struct, marshaled back to YAML and re-parsed, does not yield a valid document node. This is an internal invariant check on the 'generated' tree (the sanitized current config) used for merging back into the original file. Because yaml.Marshal of the Config struct always emits a document, hitting this indicates memory corruption, a nil-producing custom marshaller, or an upstream library inconsistency rather than a user config mistake.","triggerScenarios":"Essentially unreachable in normal operation: it fires only if yaml.Marshal(persistCfg) produces output that unmarshals to a non-document or a document with nil/empty content — e.g. a custom MarshalYAML on an embedded struct returning a nil node, or a yaml.v3 version mismatch.","commonSituations":"Building from source with an incompatible fork of gopkg.in/yaml.v3; a plugin or fork adding a type whose MarshalYAML returns invalid output; extremely unlikely for stock releases.","solutions":["If you forked or vendored yaml.v3, restore the standard library version from go.mod.","Check any custom MarshalYAML implementations you added to Config sub-structs return non-nil values.","Run 'go mod tidy' and rebuild with the pinned dependencies.","If it persists on stock code, report it upstream with the config that reproduces it."],"exampleFix":null,"handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":["Use the pinned yaml.v3 dependency from go.mod; do not vendor forks.","Ensure custom MarshalYAML methods never return nil or invalid nodes.","Run 'go mod tidy' after dependency changes."],"tags":["config","yaml","internal","invariant"],"backgroundTag":null,"analyzedSha":"78f0c4079e3e6273d65d03b5549cffc898703264","analyzedAt":"2026-08-15T12:26:37.444Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}