{"record":{"id":"e4cce704a41786e4","repo":"gotify/server","slug":"cannot-parse-config-file-s-w","errorCode":null,"errorMessage":"cannot parse config file %s: %w","messagePattern":"cannot parse config file (.+?): %w","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"config/migrate/migrate.go","lineNumber":85,"sourceCode":"\t\tUsernameClaim *string\n\t\tRedirectURL   *string\n\t\tAutoRegister  *bool\n\t\tScopes        []string\n\t}\n}\n\nfunc Config(file string) (string, error) {\n\tif file == \"\" {\n\t\treturn \"\", errors.New(\"migrate-config requires one argument: the path to the old config.yml\")\n\t}\n\tdata, err := os.ReadFile(file)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"cannot read config file %s: %w\", file, err)\n\t}\n\n\tvar migrated oldConfig\n\tif err := yaml.Unmarshal(data, &migrated); err != nil {\n\t\treturn \"\", fmt.Errorf(\"cannot parse config file %s: %w\", file, err)\n\t}\n\n\tcontent, err := godotenv.Marshal(buildEnv(migrated))\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"cannot render config: %w\", err)\n\t}\n\n\treturn content, nil\n}\n\nfunc buildEnv(c oldConfig) map[string]string {\n\tout := map[string]string{}\n\tstr := func(key string, value *string) {\n\t\tif value != nil {\n\t\t\tout[key] = *value\n\t\t}\n\t}\n\tnum := func(key string, value *int) {","sourceCodeStart":67,"sourceCodeEnd":103,"githubUrl":"https://github.com/gotify/server/blob/14bfc256276775c425f988d621dccfe705de18ac/config/migrate/migrate.go#L67-L103","documentation":"After reading the file, Config unmarshals it into the oldConfig struct with yaml.Unmarshal. If the content is not valid YAML or does not match the expected old config schema, the yaml error is wrapped as 'cannot parse config file %s: %w'.","triggerScenarios":"Running migrate-config against a file containing invalid YAML syntax (bad indentation, tabs, duplicate keys) or a YAML document whose fields cannot be decoded into oldConfig (wrong types, missing required keys).","commonSituations":"Migrating an already-converted .env file by mistake, hand-edited config that broke indentation, a config from a newer/older version with different keys, or a file with a UTF-8 BOM.","solutions":["Validate the YAML with a linter (yamllint) or yaml.Unmarshal in a scratch program to see the exact line/column of the syntax error.","Confirm the file is really the OLD config.yml format expected by oldConfig; adjust keys/types to match that schema.","Fix tabs (YAML requires spaces) and indentation; strip any BOM.","Wrap in test coverage like TestMigrateConfigErrors to catch schema drift when oldConfig changes."],"exampleFix":"// before (config.old.yml)\nserver:\n\\tport: 8080  # tab indentation, invalid YAML\n// after\nserver:\n  port: 8080  # spaces only","handlingStrategy":"validation","validationCode":"func assertValidYAML(path string) error {\n    data, err := os.ReadFile(path)\n    if err != nil { return err }\n    var v map[string]any\n    if err := yaml.Unmarshal(data, &v); err != nil {\n        return fmt.Errorf(\"%s is not valid YAML: %w\", path, err)\n    }\n    return nil\n}","typeGuard":null,"tryCatchPattern":"out, err := migrate.Config(oldPath)\nif err != nil && strings.Contains(err.Error(), \"cannot parse config file\") {\n    return fmt.Errorf(\"fix YAML in %s first (run yamllint): %w\", oldPath, err)\n}","preventionTips":["Run yamllint on the old config before migrating","Use spaces, never tabs, in YAML files","Confirm the file matches the oldConfig schema (correct keys/types) for your library version","Keep the pre-migration config under version control so bad hand-edits are visible"],"tags":["go","yaml","config-migration","parsing"],"backgroundTag":"yaml-parse-error","analyzedSha":"14bfc256276775c425f988d621dccfe705de18ac","analyzedAt":"2026-09-05T12:52:36.781Z","contentChangedAt":"2026-09-05T12:52:36.781Z","schemaVersion":2},"datasetVersion":"2026-09-12T17:17:11.597Z"}