{"record":{"id":"881c588e353e3fe8","repo":"twpayne/chezmoi","slug":"s-invalid-format-indent","errorCode":null,"errorMessage":"%s: invalid format-indent","messagePattern":"(.+?): invalid format-indent","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/chezmoi/template.go","lineNumber":50,"sourceCode":"\tFuncs          template.FuncMap\n\tFormatIndent   string\n\tLeftDelimiter  string\n\tLineEnding     string\n\tRightDelimiter string\n\tOptions        []string\n}\n\n// ParseTemplate parses a template named name from data with the given funcs and\n// templateOptions.\nfunc ParseTemplate(name string, data []byte, options TemplateOptions) (*Template, error) {\n\tcontents, err := options.parseAndRemoveDirectives(data)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tfuncs := options.Funcs\n\tif options.FormatIndent != \"\" {\n\t\tif !formatIndentRx.MatchString(options.FormatIndent) {\n\t\t\treturn nil, fmt.Errorf(\"%s: invalid format-indent\", options.FormatIndent)\n\t\t}\n\t\tfuncs = maps.Clone(funcs)\n\t\tfuncs[\"toJson\"] = func(data any) string {\n\t\t\tvar builder strings.Builder\n\t\t\tencoder := json.NewEncoder(&builder)\n\t\t\tencoder.SetIndent(\"\", options.FormatIndent)\n\t\t\tif err := encoder.Encode(data); err != nil {\n\t\t\t\tpanic(err)\n\t\t\t}\n\t\t\treturn builder.String()\n\t\t}\n\t\tfuncs[\"toToml\"] = func(data any) string {\n\t\t\tvar builder strings.Builder\n\t\t\tencoder := toml.NewEncoder(&builder)\n\t\t\tencoder.Indent = options.FormatIndent\n\t\t\tif err := encoder.Encode(data); err != nil {\n\t\t\t\tpanic(err)\n\t\t\t}","sourceCodeStart":32,"sourceCodeEnd":68,"githubUrl":"https://github.com/twpayne/chezmoi/blob/f901167e4685db90da56d6a2a19df642cb3e0247/internal/chezmoi/template.go#L32-L68","documentation":"The format-indent template option controls JSON encoder indentation and must match formatIndentRx (valid indent strings like spaces/tabs). An invalid value for format-indent aborts template parsing with '<value>: invalid format-indent'.","triggerScenarios":"A template directive like {{- /* format-indent: \"\\t \" odd value */ -}} whose value fails the formatIndentRx validation during ParseTemplate.","commonSituations":"Typo or exotic whitespace (multi-char combos, control characters) in the format-indent directive; copying an example with an unsupported indent value; confusion with format-indent-width which takes a number.","solutions":["Use a supported format-indent value such as \"  \" (two spaces) or \"\\t\" (tab)","If you want numeric indentation, use the format-indent-width directive instead","Check the regex-accepted characters: plain spaces or tabs only, no other characters"],"exampleFix":"// before in template\n{{- /* format-indent: \"\\t  \" */ -}}{{ toJson . }}\n// after\n{{- /* format-indent: \"\\t\" */ -}}{{ toJson . }}","handlingStrategy":"validation","validationCode":"// validate format-indent before parsing templates\nvar formatIndentRx = regexp.MustCompile(`^( |\\t)+$`)\nif options.FormatIndent != \"\" && !formatIndentRx.MatchString(options.FormatIndent) {\n  return fmt.Errorf(\"invalid format-indent %q: use only spaces or tabs\", options.FormatIndent)\n}","typeGuard":"func isValidFormatIndent(s string) bool { return s == \"\" || formatIndentRx.MatchString(s) }","tryCatchPattern":"tmpl, err := ParseTemplate(...)\nif err != nil && strings.Contains(err.Error(), \"invalid format-indent\") {\n  return fmt.Errorf(\"fix the format-indent directive (spaces/tabs only): %w\", err)\n}","preventionTips":["Use only \"  \" (spaces) or \"\\t\" (tab) as format-indent values","Use format-indent-width when a number is intended","Test templates with `chezmoi execute-template` before committing"],"tags":["chezmoi","template","validation"],"backgroundTag":"invalid-format-indent","analyzedSha":"f901167e4685db90da56d6a2a19df642cb3e0247","analyzedAt":"2026-09-01T18:16:41.508Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T01:17:15.007Z"}