{"record":{"id":"9db8cf6b5f8c620d","repo":"kubernetes/kops","slug":"unhandled-state-for-json-delim-serialization-v","errorCode":null,"errorMessage":"unhandled state for json delim serialization: %v %q","messagePattern":"unhandled state for json delim serialization: (.+?) %q","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/jsonutils/streamwriter.go","lineNumber":111,"sourceCode":"\t\tcase 0:\n\t\t\tif err := j.writeRaw(indent + v); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\tcase '{':\n\t\t\tif err := j.writeRaw(indent + v); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\tcase '[':\n\t\t\tif err := j.writeRaw(indent + v); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\tcase 'F':\n\t\t\tif err := j.writeRaw(v); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\n\t\tdefault:\n\t\t\treturn fmt.Errorf(\"unhandled state for json delim serialization: %v %q\", state, j.state)\n\t\t}\n\n\t\tswitch tt {\n\t\tcase json.Delim('{'):\n\t\t\tj.deferred = \"\\n\"\n\t\tcase json.Delim('['):\n\t\t\tj.deferred = \"\\n\"\n\t\tcase json.Delim(']'), json.Delim('}'):\n\t\t\tj.deferred = \",\\n\"\n\t\tdefault:\n\t\t\treturn fmt.Errorf(\"unknown delim: %v\", tt)\n\t\t}\n\n\t\treturn nil\n\n\t\t//\t\tbool, for JSON booleans\n\tcase bool:\n\t\tv = fmt.Sprintf(\"%v\", tt)","sourceCodeStart":93,"sourceCodeEnd":129,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/pkg/jsonutils/streamwriter.go#L93-L129","documentation":"When writing a delimiter token, the writer checks the last character of its internal state stack (0, '{', '[', or 'F'). Any other state character means the writer's state machine got out of sync with the token stream. This is an internal-consistency error triggered by feeding tokens in an order that cannot come from valid JSON.","triggerScenarios":"Calling WriteToken with delimiters in an inconsistent order, e.g. writing a closing ']' without a matching opening '[', or reusing one JSONStreamWriter across two independent token streams so leftover state (like 'F') leaks into the next stream.","commonSituations":"Reusing a JSONStreamWriter after aborting a previous stream mid-way; writing tokens from two decoders interleaved into one writer; writing a closing delimiter at top level.","solutions":["Use a fresh JSONStreamWriter for each JSON document/stream.","Feed tokens strictly in the order produced by json.Decoder over complete, valid JSON.","If a stream is aborted, discard the writer instead of continuing with it."],"exampleFix":"// before\nwriter := jsonutils.NewJSONStreamWriter(buf)\nwriteDoc1(writer) // aborted early\nwriteDoc2(writer) // state corrupted\n// after\nwriteDoc := func(buf *bytes.Buffer, toks []json.Token) error {\n\twriter := jsonutils.NewJSONStreamWriter(buf)\n\tfor _, t := range toks {\n\t\tif err := writer.WriteToken(t); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn nil\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"if err := writer.WriteToken(tok); err != nil {\n\treturn fmt.Errorf(\"json stream write at token %v: %w\", tok, err)\n}\n// create a new JSONStreamWriter per document; never reuse after error","preventionTips":["One JSONStreamWriter per JSON document.","Always consume the decoder to completion or discard the writer.","Never interleave tokens from two decoders into one writer."],"tags":["json","state-machine","streaming"],"backgroundTag":"json-invalid-token","analyzedSha":"4c8573c808a73d578c5eadc86d410646ea0b0d73","analyzedAt":"2026-09-05T04:13:19.212Z","contentChangedAt":"2026-09-05T04:13:19.212Z","schemaVersion":2},"datasetVersion":"2026-09-12T12:17:11.808Z"}