{"record":{"id":"922ca43ec7fb47f6","repo":"gastownhall/beads","slug":"failed-to-encode-config-yaml-w","errorCode":null,"errorMessage":"failed to encode config.yaml: %w","messagePattern":"failed to encode config\\.yaml: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/config/repos.go","lineNumber":144,"sourceCode":"\t\t\t// Remove repos section entirely if empty\n\t\t\tmapping.Content = append(mapping.Content[:reposIndex], mapping.Content[reposIndex+2:]...)\n\t\t} else {\n\t\t\tmapping.Content[reposIndex+1] = reposNode\n\t\t}\n\t} else if reposNode != nil {\n\t\t// Add new repos section at the end\n\t\tmapping.Content = append(mapping.Content,\n\t\t\t&yaml.Node{Kind: yaml.ScalarNode, Value: \"repos\"},\n\t\t\treposNode,\n\t\t)\n\t}\n\n\t// Marshal back to YAML\n\tvar buf strings.Builder\n\tencoder := yaml.NewEncoder(&buf)\n\tencoder.SetIndent(2)\n\tif err := encoder.Encode(&root); err != nil {\n\t\treturn fmt.Errorf(\"failed to encode config.yaml: %w\", err)\n\t}\n\tif err := encoder.Close(); err != nil {\n\t\treturn fmt.Errorf(\"failed to close encoder: %w\", err)\n\t}\n\n\t// Write back to file\n\tif err := os.WriteFile(configPath, []byte(buf.String()), 0600); err != nil {\n\t\treturn fmt.Errorf(\"failed to write config.yaml: %w\", err)\n\t}\n\n\t// Reload viper config so changes take effect immediately\n\tif v != nil {\n\t\tif err := v.ReadInConfig(); err != nil {\n\t\t\t// Not fatal - config is on disk, will be picked up on next command\n\t\t\t_ = err // Best effort: viper reload failure is non-fatal since config was already written to disk\n\t\t}\n\t}\n","sourceCodeStart":126,"sourceCodeEnd":162,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/config/repos.go#L126-L162","documentation":"SetReposInYAML re-encodes the modified yaml.Node tree via a yaml.Encoder. If Encode fails (rare — usually only from invalid node contents such as a nil/invalid node in the tree), the error is wrapped as \"failed to encode config.yaml\".","triggerScenarios":"encoder.Encode(&root) returns an error, typically from an invalid yaml.Node value inserted into the tree (e.g. zero-value nodes with Kind 0) or an unencodable value.","commonSituations":"A custom build or patched config-construction code injected an invalid node; running against a corrupted in-memory tree rather than a user mistake in most cases.","solutions":["Inspect the code that builds/mutates the yaml.Node tree for zero-value nodes (Kind must be set)","Ensure all nodes appended carry a valid Kind, Style, and Value/Content","Upgrade gopkg.in/yaml.v3 — some encode bugs were fixed in later versions","If reproducible, marshal a plain struct instead of a Node tree to isolate the bad value"],"exampleFix":"// before\nnode := yaml.Node{} // Kind not set -> encode error\n// after\nnode := yaml.Node{Kind: yaml.ScalarNode, Value: repoPath}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"if err := SetReposInYAML(cfgPath, repos); err != nil {\n    if strings.Contains(err.Error(), \"failed to encode\") {\n        log.Printf(\"node tree invalid, update yaml.v3: %v\", err)\n    }\n    return err\n}","preventionTips":["Pin gopkg.in/yaml.v3 to a recent version","Only insert fully-populated yaml.Node values (set Kind/Style/Value)","Prefer building config from typed structs when structure preservation is not needed","Report reproducible encode failures upstream"],"tags":["yaml","encoding","config"],"backgroundTag":"yaml-encode-error","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}