{"record":{"id":"94b94df5a987d556","repo":"mikefarah/yq","slug":"must-use-variable-with-a-pipe-e-g-exp-as-x","errorCode":null,"errorMessage":"must use variable with a pipe, e.g. `exp as $x | ...`","messagePattern":"must use variable with a pipe, e\\.g\\. `exp as \\$x \\| \\.\\.\\.`","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/yqlib/operator_variables.go","lineNumber":23,"sourceCode":"\t\"fmt\"\n)\n\nfunc getVariableOperator(_ *dataTreeNavigator, context Context, expressionNode *ExpressionNode) (Context, error) {\n\tvariableName := expressionNode.Operation.StringValue\n\tlog.Debugf(\"getVariableOperator %v\", variableName)\n\tresult := context.GetVariable(variableName)\n\tif result == nil {\n\t\tresult = list.New()\n\t}\n\treturn context.ChildContext(result), nil\n}\n\ntype assignVarPreferences struct {\n\tIsReference bool\n}\n\nfunc useWithPipe(_ *dataTreeNavigator, _ Context, _ *ExpressionNode) (Context, error) {\n\treturn Context{}, fmt.Errorf(\"must use variable with a pipe, e.g. `exp as $x | ...`\")\n}\n\n// variables are like loops in jq\n// https://stedolan.github.io/jq/manual/#Variable\nfunc variableLoop(d *dataTreeNavigator, context Context, originalExp *ExpressionNode) (Context, error) {\n\tlog.Debug(\"variable loop!\")\n\tresults := list.New()\n\tvar evaluateAllTogether = true\n\tfor matchEl := context.MatchingNodes.Front(); matchEl != nil; matchEl = matchEl.Next() {\n\t\tevaluateAllTogether = evaluateAllTogether && matchEl.Value.(*CandidateNode).EvaluateTogether\n\t\tif !evaluateAllTogether {\n\t\t\tbreak\n\t\t}\n\t}\n\tif evaluateAllTogether {\n\t\treturn variableLoopSingleChild(d, context, originalExp)\n\t}\n","sourceCodeStart":5,"sourceCodeEnd":41,"githubUrl":"https://github.com/mikefarah/yq/blob/8b5af0694bb82b41d4ae180fac9972029066f90a/pkg/yqlib/operator_variables.go#L5-L41","documentation":"The `as` variable-binding operator only makes sense inside a pipeline (`exp as $x | ...`). yq parses variables so that, when used outside a pipe context, the placeholder handler `useWithPipe` runs and returns this error instead of silently doing nothing.","triggerScenarios":"Using a variable operator form that is not attached to a pipe, e.g. `yq '$x'` with no binding, or an expression where `as` isn't followed by `|`, causing the lexer to dispatch to useWithPipe.","commonSituations":"Copy-pasting jq snippets without the trailing pipe, forgetting the `| ...` continuation after `as $x`, or writing `yq 'exp as $x'` and expecting the binding to persist to a later invocation.","solutions":["Add the pipe and continuation, e.g. `.a as $x | .b + $x`","If you only wanted to reference a value, drop the `as` syntax and pipe the expression directly","Check the expression string for truncation — the `| ...` half may have been lost when quoting in the shell","Consult the variables docs: bindings are per-expression, not persistent across yq runs"],"exampleFix":"// before\nyq '.a as $x' file.yaml\n// after\nyq '.a as $x | .b + $x' file.yaml\n","handlingStrategy":"try-catch","validationCode":"// Validate expression has a pipe continuation after 'as'\nif strings.Contains(expr, \" as $\") && !strings.Contains(expr, \"|\") {\n\treturn fmt.Errorf(\"'as' requires a pipe continuation: exp as $x | ...\")\n}","typeGuard":null,"tryCatchPattern":"out, err := yqEval(expr, doc)\nif err != nil && strings.Contains(err.Error(), \"must use variable with a pipe\") {\n\t// fix expression: append '| ...' continuation\n}","preventionTips":["Always follow `as $x` with `|` and a consuming expression","Test expressions in the shell with single quotes to avoid mangling","Refer to yq variable docs when porting jq snippets"],"tags":["yaml","variables","expression-syntax"],"backgroundTag":"expression-syntax-invalid","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"}