{"record":{"id":"f3fe50e334bdfff1","repo":"AdguardTeam/AdGuardHome","slug":"parsing-config-file-for-upgrade-w","errorCode":null,"errorMessage":"parsing config file for upgrade: %w","messagePattern":"parsing config file for upgrade: %w","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/configmigrate/migrator.go","lineNumber":53,"sourceCode":"\t\tlogger:     c.Logger,\n\t\tworkingDir: c.WorkingDir,\n\t\tdataDir:    c.DataDir,\n\t}\n}\n\n// Migrate preforms necessary upgrade operations to upgrade file to target\n// schema version, if needed.  It returns the body of the upgraded config file,\n// whether the file was upgraded, and an error, if any.  If upgraded is false,\n// the body is the same as the input.\nfunc (m *Migrator) Migrate(\n\tctx context.Context,\n\tbody []byte,\n\ttarget uint,\n) (newBody []byte, upgraded bool, err error) {\n\tdiskConf := yobj{}\n\terr = yaml.Unmarshal(body, &diskConf)\n\tif err != nil {\n\t\treturn body, false, fmt.Errorf(\"parsing config file for upgrade: %w\", err)\n\t}\n\n\tcurrentInt, _, err := fieldVal[int](diskConf, \"schema_version\")\n\tif err != nil {\n\t\t// Don't wrap the error, since it's informative enough as is.\n\t\treturn body, false, err\n\t}\n\n\tcurrent := uint(currentInt)\n\tm.logger.DebugContext(ctx, \"got\", \"schema_version\", current)\n\n\tif err = validateVersion(current, target); err != nil {\n\t\t// Don't wrap the error, since it's informative enough as is.\n\t\treturn body, false, err\n\t} else if current == target {\n\t\treturn body, false, nil\n\t}\n","sourceCodeStart":35,"sourceCodeEnd":71,"githubUrl":"https://github.com/AdguardTeam/AdGuardHome/blob/b41aefbe51c8dde65e2c50f093996afa0502edf9/internal/configmigrate/migrator.go#L35-L71","documentation":"Migrate fails to YAML-parse the configuration file body before upgrading its schema. The yaml.Unmarshal error is wrapped, so syntax problems (bad indentation, tabs, invalid scalars) are reported with position info.","triggerScenarios":"Calling Migrate with a body that is not valid YAML, e.g. a tab-indented file, unbalanced quotes, or a truncated/corrupted config.","commonSituations":"Hand-edited YAML.yaml with tabs or copy-paste artifacts, a config file corrupted by an interrupted write, feeding JSON or encrypted data to the migrator.","solutions":["Run a YAML linter or `yaml.Unmarshal` on the file to locate the syntax error reported in the wrapped cause","Restore the config from backup or re-download it if corrupted","Fix indentation (spaces, not tabs) and quoting, then retry Migrate"],"exampleFix":"# before (tabs)\nusers:\n\t- name: admin\n\n# after (spaces)\nusers:\n  - name: admin","handlingStrategy":"validation","validationCode":"var probe map[string]any\nif err := yaml.Unmarshal(body, &probe); err != nil { /* fix YAML before Migrate */ }","typeGuard":null,"tryCatchPattern":"if _, _, err := configmigrate.Migrate(ctx, body, target); err != nil && strings.Contains(err.Error(), \"parsing config file for upgrade\") { /* report syntax error with position from wrapped cause */ }","preventionTips":["Never edit YAML with tabs; use spaces only","Validate configs in CI with a YAML parser before shipping"],"tags":["config","yaml","migration","parse"],"backgroundTag":"yaml-parse-error","analyzedSha":"b41aefbe51c8dde65e2c50f093996afa0502edf9","analyzedAt":"2026-08-27T04:57:55.097Z","schemaVersion":2},"datasetVersion":"2026-08-27T08:17:20.692Z"}