kubernetes/kops · error

unhandled state for json delim serialization: %v %q

Error message

unhandled state for json delim serialization: %v %q

What it means

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.

Source

Thrown at pkg/jsonutils/streamwriter.go:111

		case 0:
			if err := j.writeRaw(indent + v); err != nil {
				return err
			}
		case '{':
			if err := j.writeRaw(indent + v); err != nil {
				return err
			}
		case '[':
			if err := j.writeRaw(indent + v); err != nil {
				return err
			}
		case 'F':
			if err := j.writeRaw(v); err != nil {
				return err
			}

		default:
			return fmt.Errorf("unhandled state for json delim serialization: %v %q", state, j.state)
		}

		switch tt {
		case json.Delim('{'):
			j.deferred = "\n"
		case json.Delim('['):
			j.deferred = "\n"
		case json.Delim(']'), json.Delim('}'):
			j.deferred = ",\n"
		default:
			return fmt.Errorf("unknown delim: %v", tt)
		}

		return nil

		//		bool, for JSON booleans
	case bool:
		v = fmt.Sprintf("%v", tt)

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Use a fresh JSONStreamWriter for each JSON document/stream.
  2. Feed tokens strictly in the order produced by json.Decoder over complete, valid JSON.
  3. If a stream is aborted, discard the writer instead of continuing with it.

Example fix

// before
writer := jsonutils.NewJSONStreamWriter(buf)
writeDoc1(writer) // aborted early
writeDoc2(writer) // state corrupted
// after
writeDoc := func(buf *bytes.Buffer, toks []json.Token) error {
	writer := jsonutils.NewJSONStreamWriter(buf)
	for _, t := range toks {
		if err := writer.WriteToken(t); err != nil {
			return err
		}
	}
	return nil
}
Defensive patterns

Strategy: try-catch

Try / catch

if err := writer.WriteToken(tok); err != nil {
	return fmt.Errorf("json stream write at token %v: %w", tok, err)
}
// create a new JSONStreamWriter per document; never reuse after error

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05). Data as JSON: /api/errors/9db8cf6b5f8c620d. Report an issue: GitHub.