{"record":{"id":"d127419827ee8ead","repo":"ory/hydra","slug":"could-not-parse-template-s","errorCode":null,"errorMessage":"could not parse template %s","messagePattern":"could not parse template (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"oryx/popx/migration_content.go","lineNumber":24,"sourceCode":"import (\n\t\"bytes\"\n\t\"text/template\"\n\n\t\"github.com/pkg/errors\"\n\n\t\"github.com/ory/pop/v6\"\n\t\"github.com/ory/x/dbal\"\n)\n\nfunc ParameterizedMigrationContent(params map[string]interface{}) func(mf Migration, c *pop.Connection, r []byte, usingTemplate bool) (string, error) {\n\treturn func(mf Migration, c *pop.Connection, b []byte, usingTemplate bool) (string, error) {\n\t\tcontent := \"\"\n\t\tif usingTemplate {\n\t\t\tt := template.New(\"migration\")\n\t\t\tt.Funcs(SQLTemplateFuncs)\n\t\t\tt, err := t.Parse(string(b))\n\t\t\tif err != nil {\n\t\t\t\treturn \"\", errors.Wrapf(err, \"could not parse template %s\", mf.Path)\n\t\t\t}\n\t\t\tvar bb bytes.Buffer\n\t\t\terr = t.Execute(&bb, struct {\n\t\t\t\tIsSQLite       bool\n\t\t\t\tIsCockroach    bool\n\t\t\t\tIsMySQL        bool\n\t\t\t\tIsMariaDB      bool\n\t\t\t\tIsPostgreSQL   bool\n\t\t\t\tDialectDetails *pop.ConnectionDetails\n\t\t\t\tParameters     map[string]interface{}\n\t\t\t}{\n\t\t\t\tIsSQLite:       c.Dialect.Name() == \"sqlite3\",\n\t\t\t\tIsCockroach:    c.Dialect.Name() == \"cockroach\",\n\t\t\t\tIsMySQL:        c.Dialect.Name() == \"mysql\",\n\t\t\t\tIsMariaDB:      c.Dialect.Name() == \"mariadb\",\n\t\t\t\tIsPostgreSQL:   dbal.IsPostgresCompatible(c.Dialect.Name()),\n\t\t\t\tDialectDetails: c.Dialect.Details(),\n\t\t\t\tParameters:     params,","sourceCodeStart":6,"sourceCodeEnd":42,"githubUrl":"https://github.com/ory/hydra/blob/4174065ffb052799890f7480f5360a877a67ffc1/oryx/popx/migration_content.go#L6-L42","documentation":"When a migration file is a template (usingTemplate is true), its content is parsed with Go's text/template (with SQLTemplateFuncs registered). If template.Parse fails on the file bytes, the underlying parse error is wrapped with 'could not parse template %s' naming the migration file path.","triggerScenarios":"A .sql migration containing malformed Go template syntax — e.g. an unclosed {{ if }}, unknown template function, or stray {{ }} — passed through the templated migration path.","commonSituations":"Typos in template directives like {{ if .IsSQLite }} without an {{ end }}; calling a func not present in SQLTemplateFuncs; editing a templated migration and breaking syntax; copy-pasting SQL containing '{{' sequences.","solutions":["Open the migration file named in the message and fix the template syntax (balance {{ if }}/{{ end }}, {{ range }})","Verify any called functions exist in SQLTemplateFuncs","Escape literal braces that must not be interpreted as template actions","Test the template by running the migration against a dev database to confirm it parses"],"exampleFix":"// before (migration.up.sql)\n{{ if .IsSQLite }}CREATE TABLE t... \n// after\n{{ if .IsSQLite }}CREATE TABLE t...{{ end }}","handlingStrategy":"validation","validationCode":"// Pre-validate template syntax of migration files before running migrations\nfunc templateParses(path string) error {\n  b, err := os.ReadFile(path)\n  if err != nil { return err }\n  t := template.New(\"check\").Funcs(popx.SQLTemplateFuncs)\n  _, err = t.Parse(string(b))\n  return err\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Run a lint step that parses all .sql migrations as templates in CI","Balance every {{ if }}/{{ range }} with {{ end }} before committing","Escape literal '{{' in SQL with a delims change or template comment","Only call functions documented in SQLTemplateFuncs"],"tags":["migrations","go","templates","sql"],"backgroundTag":"template-parse-error","analyzedSha":"4174065ffb052799890f7480f5360a877a67ffc1","analyzedAt":"2026-09-03T14:52:41.581Z","contentChangedAt":"2026-09-03T14:52:41.581Z","schemaVersion":2},"datasetVersion":"2026-09-10T17:17:09.494Z"}