{"record":{"id":"54e70fa6195c45dc","repo":"mikefarah/yq","slug":"unsupported-character-q-in-raw-hcl-expression","errorCode":null,"errorMessage":"unsupported character %q in raw HCL expression","messagePattern":"unsupported character %q in raw HCL expression","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/yqlib/encoder_hcl.go","lineNumber":349,"sourceCode":"\t\t\tcontinue\n\t\tcase ch == '(':\n\t\t\ttokens = append(tokens, &hclwrite.Token{Type: hclsyntax.TokenOParen, Bytes: []byte{'('}})\n\t\tcase ch == ')':\n\t\t\ttokens = append(tokens, &hclwrite.Token{Type: hclsyntax.TokenCParen, Bytes: []byte{')'}})\n\t\tcase ch == ',':\n\t\t\ttokens = append(tokens, &hclwrite.Token{Type: hclsyntax.TokenComma, Bytes: []byte{','}})\n\t\tcase ch == '.':\n\t\t\ttokens = append(tokens, &hclwrite.Token{Type: hclsyntax.TokenDot, Bytes: []byte{'.'}})\n\t\tcase ch == '+':\n\t\t\ttokens = append(tokens, &hclwrite.Token{Type: hclsyntax.TokenPlus, Bytes: []byte{'+'}})\n\t\tcase ch == '-':\n\t\t\ttokens = append(tokens, &hclwrite.Token{Type: hclsyntax.TokenMinus, Bytes: []byte{'-'}})\n\t\tcase ch == '*':\n\t\t\ttokens = append(tokens, &hclwrite.Token{Type: hclsyntax.TokenStar, Bytes: []byte{'*'}})\n\t\tcase ch == '/':\n\t\t\ttokens = append(tokens, &hclwrite.Token{Type: hclsyntax.TokenSlash, Bytes: []byte{'/'}})\n\t\tdefault:\n\t\t\treturn nil, fmt.Errorf(\"unsupported character %q in raw HCL expression\", ch)\n\t\t}\n\t\ti++\n\t}\n\treturn tokens, nil\n}\n\n// encodeAttribute encodes a value as an HCL attribute\nfunc (he *hclEncoder) encodeAttribute(body *hclwrite.Body, key string, valueNode *CandidateNode) error {\n\tif valueNode.Kind == ScalarNode && valueNode.Tag == \"!!str\" {\n\t\t// Handle unquoted expressions (as-is, without quotes)\n\t\tif valueNode.Style == 0 {\n\t\t\ttokens, err := tokensForRawHCLExpr(valueNode.Value)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tbody.SetAttributeRaw(key, tokens)\n\t\t\treturn nil\n\t\t}","sourceCodeStart":331,"sourceCodeEnd":367,"githubUrl":"https://github.com/mikefarah/yq/blob/8b5af0694bb82b41d4ae180fac9972029066f90a/pkg/yqlib/encoder_hcl.go#L331-L367","documentation":"When encoding an attribute whose value is a raw HCL expression, yq tokenizes the string character-by-character and only supports a fixed set of operators/characters. Any other character in a raw expression string raises this error.","triggerScenarios":"Encoding a mapping value marked as raw HCL (e.g. values styled/raw strings like `${var.x}` or function calls `foo(bar)`) where the string contains characters outside the supported token set (identifiers, digits, dots, +, -, *, /, etc.), such as parentheses, braces, or comparison operators.","commonSituations":"Terraform users storing `${...}` interpolations or `lookup(a, \"b\")` style expressions in YAML and expecting `to hcl` to emit them verbatim; template characters like `%` or `?` in raw strings.","solutions":["Restrict raw expressions to the supported token set (identifiers, numbers, dots, + - * /)","Replace unsupported constructs with supported HCL equivalents before encoding","Drop the raw-expression styling so the value is encoded as a normal string literal","Extend tokensForRawHCLExpr if you maintain a fork and need more characters"],"exampleFix":"// before (value flagged as raw expr): \"${var.x}\"\n// after: use \"var.x\" as the raw expression, or remove raw styling to emit a quoted string","handlingStrategy":"validation","validationCode":"// allow-list check before marking a value as raw HCL:\nvar rawExprAllowed = regexp.MustCompile(`^[A-Za-z0-9_.+\\-*/ ]+$`)\nfunc safeRawExpr(s string) bool { return rawExprAllowed.MatchString(s) }","typeGuard":"func isSupportedRawExpr(s string) bool {\n  for _, ch := range s {\n    switch { case ch >= 'a' && ch <= 'z', ch >= 'A' && ch <= 'Z',\n      ch >= '0' && ch <= '9',\n      strings.ContainsRune(\"._+-*/ \", ch):\n    default: return false }\n  }\n  return len(s) > 0\n}","tryCatchPattern":"toks, err := tokensForRawHCLExpr(expr)\nif err != nil {\n    // fall back: encode as a quoted string literal instead of a raw expression\n    return writeStringLiteral(body, key, expr)\n}","preventionTips":["Keep raw expressions limited to identifiers, numbers, dots, and + - * /","Avoid ${...} interpolations, function-call parens, and comparison ops in raw values","Fall back to string-literal encoding when validation fails"],"tags":["hcl","encoding","raw-expression","unsupported-character","yq"],"backgroundTag":"hcl-raw-expression-unsupported-character","analyzedSha":"8b5af0694bb82b41d4ae180fac9972029066f90a","analyzedAt":"2026-09-05T10:57:22.766Z","contentChangedAt":"2026-09-05T10:57:22.766Z","schemaVersion":2},"datasetVersion":"2026-09-12T17:17:11.597Z"}