{"record":{"id":"e3faac1144e5504a","repo":"tomnomnom/gron","slug":"statement-has-no-value","errorCode":null,"errorMessage":"statement has no value","messagePattern":"statement has no value","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"ungron.go","lineNumber":374,"sourceCode":"// ungronTokens turns a slice of tokens into an actual datastructure\nfunc ungronTokens(ts []token) (interface{}, error) {\n\tif len(ts) == 0 {\n\t\treturn nil, errRecoverable{\"empty input\"}\n\t}\n\n\tif ts[0].typ == typIgnored {\n\t\treturn nil, errRecoverable{\"ignored token\"}\n\t}\n\n\tif ts[len(ts)-1].typ == typError {\n\t\treturn nil, errors.New(\"invalid statement\")\n\t}\n\n\t// The last token should be typSemi so we need to check\n\t// the second to last token is a value rather than the\n\t// last one\n\tif len(ts) > 1 && !ts[len(ts)-2].isValue() {\n\t\treturn nil, errors.New(\"statement has no value\")\n\t}\n\n\tt := ts[0]\n\tswitch {\n\tcase t.isPunct():\n\t\t// Skip the token\n\t\tval, err := ungronTokens(ts[1:])\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\treturn val, nil\n\n\tcase t.isValue():\n\t\tvar val interface{}\n\t\td := json.NewDecoder(strings.NewReader(t.text))\n\t\td.UseNumber()\n\t\terr := d.Decode(&val)\n\t\tif err != nil {","sourceCodeStart":356,"sourceCodeEnd":392,"githubUrl":"https://github.com/tomnomnom/gron/blob/88a6234ea2d0c487090988182ad9a7cdf6def924/ungron.go#L356-L392","documentation":"ungronTokens expects a statement whose second-to-last token is a value (the last token is always ';'). If the token before the trailing semicolon is not a value, the statement has no assigned value and ungronTokens returns \"statement has no value\".","triggerScenarios":"`gron --ungron` on lines like `json.a =;` or `json.a;` — statements truncated so the '=' is immediately followed by ';', or the value token was dropped by prior text manipulation.","commonSituations":"Line-based editing (sed/awk/cut) that chopped off the value; diff/patch artifacts; manually constructed statements missing the RHS.","solutions":["Ensure every input line has a value between '=' and ';'","Regenerate the input with `gron` instead of editing statement text","Pre-validate lines with a regex like ^json.*= .+;$ before ungron"],"exampleFix":"// before\njson.a =;   // no value\n\n// after\njson.a = null;","handlingStrategy":"validation","validationCode":"re := regexp.MustCompile(`^\\s*json.*=\\s*[^;]+;\\s*$`)\nif !re.MatchString(line) {\n\t// line lacks a value; reject before ungron\n}","typeGuard":"func statementHasValue(s statement) bool {\n\treturn len(s) > 1 && s[len(s)-2].isValue()\n}","tryCatchPattern":"v, err := ungronTokens(ts)\nif err != nil {\n\tif err.Error() == \"statement has no value\" {\n\t\t// fix or skip the offending statement\n\t}\n\treturn err\n}","preventionTips":["Never edit gron output with line-chopping tools without re-checking the RHS","Regex-validate `= value;` presence per line before ungron","Regenerate statements instead of hand-editing"],"tags":["go","gron","statements","parsing"],"backgroundTag":"invalid-argument-format","analyzedSha":"88a6234ea2d0c487090988182ad9a7cdf6def924","analyzedAt":"2026-09-06T11:35:31.658Z","contentChangedAt":"2026-09-06T11:35:31.658Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}