{"record":{"id":"5dd7d29f0e749faf","repo":"tomnomnom/gron","slug":"non-assignment-statement","errorCode":null,"errorMessage":"non-assignment statement","messagePattern":"non-assignment statement","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"statements.go","lineNumber":79,"sourceCode":"\treturn append(\n\t\tnew,\n\t\ttoken{\".\", typDot},\n\t\ttoken{k, typBare},\n\t)\n}\n\n// jsonify converts an assignment statement to a JSON representation\nfunc (s statement) jsonify() (statement, error) {\n\t// If m is the number of keys occurring in the left hand side\n\t// of s, then len(s) is in between 2*m+4 and 3*m+4. The resultant\n\t// statement j (carrying the JSON representation) is always 2*m+5\n\t// long. So len(s)+1 ≥ 2*m+5 = len(j). Therefore an initaial\n\t// allocation of j with capacity len(s)+1 will allow us to carry\n\t// through without reallocation.\n\tj := make(statement, 0, len(s)+1)\n\tif len(s) < 4 || s[0].typ != typBare || s[len(s)-3].typ != typEquals ||\n\t\ts[len(s)-1].typ != typSemi {\n\t\treturn nil, errors.New(\"non-assignment statement\")\n\t}\n\n\tj = append(j, token{\"[\", typLBrace})\n\tj = append(j, token{\"[\", typLBrace})\n\tfor _, t := range s[1 : len(s)-3] {\n\t\tswitch t.typ {\n\t\tcase typNumericKey, typQuotedKey:\n\t\t\tj = append(j, t)\n\t\t\tj = append(j, token{\",\", typComma})\n\t\tcase typBare:\n\t\t\tj = append(j, token{quoteString(t.text), typQuotedKey})\n\t\t\tj = append(j, token{\",\", typComma})\n\t\t}\n\t}\n\tif j[len(j)-1].typ == typComma {\n\t\tj = j[:len(j)-1]\n\t}\n\tj = append(j, token{\"]\", typLBrace})","sourceCodeStart":61,"sourceCodeEnd":97,"githubUrl":"https://github.com/tomnomnom/gron/blob/88a6234ea2d0c487090988182ad9a7cdf6def924/statements.go#L61-L97","documentation":"statement.jsonify() converts a gron assignment statement into a JSON-equivalent form. It only accepts statements that look like a complete assignment: at least 4 tokens, starting with a bare word, with '=' as the third-to-last token and ';' as the last. If the token slice doesn't match this shape, jsonify returns \"non-assignment statement\".","triggerScenarios":"Calling jsonify() on a statement built from tokens that are not a full `key = value;` assignment — e.g. a bare-key fragment with no '=' terminator, an empty or truncated statement, or a prefix statement missing the trailing semicolon.","commonSituations":"Piping `gron --json` output back through gron's JSON-formatted path, or programmatically constructing statement tokens and calling jsonify on partial statements (e.g. key-only fragments produced while building output incrementally).","solutions":["Ensure the statement ends with '=' followed by a value and a ';' before calling jsonify","Only call jsonify on statements produced by statementsFromJSON / the gron pipeline, not on hand-assembled token fragments","Check statement length and token types (s[0].typ == typBare, s[len-3].typ == typEquals, s[len-1].typ == typSemi) before calling jsonify"],"exampleFix":"// before\ns := statement{{\"json\", typBare}}\nj, err := s.jsonify() // non-assignment statement\n\n// after\ns := statement{{\"json\", typBare}, {\"=\", typEquals}, {\"null\", typNull}, {\";\", typSemi}}\nj, err := s.jsonify() // ok","handlingStrategy":"validation","validationCode":"func isAssignment(s statement) bool {\n\treturn len(s) >= 4 && s[0].typ == typBare &&\n\t\ts[len(s)-3].typ == typEquals && s[len(s)-1].typ == typSemi\n}\nif !isAssignment(s) { /* skip or fix before calling jsonify */ }","typeGuard":"func isAssignment(s statement) bool {\n\treturn len(s) >= 4 && s[0].typ == typBare &&\n\t\ts[len(s)-3].typ == typEquals && s[len(s)-1].typ == typSemi\n}","tryCatchPattern":"j, err := s.jsonify()\nif err != nil {\n\tif err.Error() == \"non-assignment statement\" {\n\t\t// skip fragment / log and continue\n\t}\n\treturn err\n}","preventionTips":["Only jsonify complete `key = value;` statements","Assert statement shape (bare head, '=', value, ';') before conversion","Avoid jsonify on partial/intermediate token fragments"],"tags":["go","gron","statements","validation"],"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-14T00:17:10.932Z"}