gotify/server · error

cannot parse config file %s: %w

Error message

cannot parse config file %s: %w

What it means

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'.

Source

Thrown at config/migrate/migrate.go:85

		UsernameClaim *string
		RedirectURL   *string
		AutoRegister  *bool
		Scopes        []string
	}
}

func Config(file string) (string, error) {
	if file == "" {
		return "", errors.New("migrate-config requires one argument: the path to the old config.yml")
	}
	data, err := os.ReadFile(file)
	if err != nil {
		return "", fmt.Errorf("cannot read config file %s: %w", file, err)
	}

	var migrated oldConfig
	if err := yaml.Unmarshal(data, &migrated); err != nil {
		return "", fmt.Errorf("cannot parse config file %s: %w", file, err)
	}

	content, err := godotenv.Marshal(buildEnv(migrated))
	if err != nil {
		return "", fmt.Errorf("cannot render config: %w", err)
	}

	return content, nil
}

func buildEnv(c oldConfig) map[string]string {
	out := map[string]string{}
	str := func(key string, value *string) {
		if value != nil {
			out[key] = *value
		}
	}
	num := func(key string, value *int) {

View on GitHub (pinned to 14bfc25627)

Solutions

  1. Validate the YAML with a linter (yamllint) or yaml.Unmarshal in a scratch program to see the exact line/column of the syntax error.
  2. Confirm the file is really the OLD config.yml format expected by oldConfig; adjust keys/types to match that schema.
  3. Fix tabs (YAML requires spaces) and indentation; strip any BOM.
  4. Wrap in test coverage like TestMigrateConfigErrors to catch schema drift when oldConfig changes.

Example fix

// before (config.old.yml)
server:
\tport: 8080  # tab indentation, invalid YAML
// after
server:
  port: 8080  # spaces only
Defensive patterns

Strategy: validation

Validate before calling

func assertValidYAML(path string) error {
    data, err := os.ReadFile(path)
    if err != nil { return err }
    var v map[string]any
    if err := yaml.Unmarshal(data, &v); err != nil {
        return fmt.Errorf("%s is not valid YAML: %w", path, err)
    }
    return nil
}

Try / catch

out, err := migrate.Config(oldPath)
if err != nil && strings.Contains(err.Error(), "cannot parse config file") {
    return fmt.Errorf("fix YAML in %s first (run yamllint): %w", oldPath, err)
}

Prevention

When it happens

Trigger: 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).

Common situations: 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.

Related errors


AI-assisted analysis of gotify/server@14bfc25627 (2026-09-05). Data as JSON: /api/errors/e4cce704a41786e4. Report an issue: GitHub.