{"record":{"id":"1c1b60468527e840","repo":"docker/cli","slug":"invalid-interpolation-format-for-s-v-you-may","errorCode":null,"errorMessage":"invalid interpolation format for %s: %#v; you may need to escape any $ with another $","messagePattern":"invalid interpolation format for (.+?): %#v; you may need to escape any \\$ with another \\$","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cli/compose/interpolation/interpolation.go","lineNumber":107,"sourceCode":"\t\t\tinterpolatedElem, err := recursiveInterpolate(elem, path.Next(PathMatchList), opts)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tout[i] = interpolatedElem\n\t\t}\n\t\treturn out, nil\n\n\tdefault:\n\t\treturn value, nil\n\t}\n}\n\nfunc newPathError(path Path, err error) error {\n\tswitch err := err.(type) {\n\tcase nil:\n\t\treturn nil\n\tcase *template.InvalidTemplateError:\n\t\treturn fmt.Errorf(\n\t\t\t\"invalid interpolation format for %s: %#v; you may need to escape any $ with another $\",\n\t\t\tpath, err.Template)\n\tdefault:\n\t\treturn fmt.Errorf(\"error while interpolating %s: %w\", path, err)\n\t}\n}\n\nconst pathSeparator = \".\"\n\n// PathMatchAll is a token used as part of a Path to match any key at that level\n// in the nested structure\nconst PathMatchAll = \"*\"\n\n// PathMatchList is a token used as part of a Path to match items in a list\nconst PathMatchList = \"[]\"\n\n// Path is a dotted path of keys to a value in a nested mapping structure. A *\n// section in a path will match any key in the mapping structure.","sourceCodeStart":89,"sourceCodeEnd":125,"githubUrl":"https://github.com/docker/cli/blob/4f84911bfe8811e9b028e4b1fee8e7510be79387/cli/compose/interpolation/interpolation.go#L89-L125","documentation":"Returned by newPathError when the template engine raises an *template.InvalidTemplateError, meaning the interpolation expression is syntactically malformed (interpolation.go:106-109). Common forms are an unclosed ${, a stray $, or unsupported brace syntax; the message suggests escaping $ as $$.","triggerScenarios":"A compose value contains a malformed interpolation such as ${VAR, ${VAR without closing brace, or an unescaped $ followed by non-template text. Substitute returns *template.InvalidTemplateError, which newPathError reformats.","commonSituations":"Including a literal dollar sign (e.g. a password, a shell var) without escaping as $$; partial copy of a template; editor stripped a closing brace; referencing $$ for non-interpolation purposes.","solutions":["Escape literal dollar signs as $$ so the parser treats them literally.","Close any unclosed ${ ... } expressions and verify variable name syntax.","If the value is not meant to be interpolated, replace $ with $$."],"exampleFix":"# before\nenvironment:\n  PASSWORD: pa$$word!\n# after\nenvironment:\n  PASSWORD: pa$$word!  # literal $ preserved","handlingStrategy":"validation","validationCode":"// Detect unescaped $ / malformed templates before interpolation.\nvar dollarRe = regexp.MustCompile(`\\$\\{[^}]*$|\\$\\{`) // very rough: unclosed brace\nfunc warnBadTemplates(values []string) {\n    for _, v := range values {\n        if dollarRe.MatchString(v) {\n            log.Warnf(\"possible malformed interpolation in %q; escape literal $ as $$\", v)\n        }\n    }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Escape literal dollar signs as $$ in compose values.","Ensure every ${ is closed by } and uses a valid variable name.","Lint compose files for stray $ characters."],"tags":["compose","interpolation","template","syntax"],"backgroundTag":null,"analyzedSha":"4f84911bfe8811e9b028e4b1fee8e7510be79387","analyzedAt":"2026-08-07T12:15:29.814Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}