···2525 | Invalid_tag_directive of string
2626 | Reserved_directive of string
2727 | Illegal_flow_key_line (** Key and : must be on same line in flow context *)
2828+ | Block_sequence_disallowed (** Block sequence entries not allowed in this context *)
28292930 (* Parser errors *)
3031 | Unexpected_token of string
···125126 | Invalid_tag_directive s -> Printf.sprintf "invalid TAG directive: %s" s
126127 | Reserved_directive s -> Printf.sprintf "reserved directive: %s" s
127128 | Illegal_flow_key_line -> "key and ':' must be on the same line in flow context"
129129+ | Block_sequence_disallowed -> "block sequence entries are not allowed in this context"
128130 | Unexpected_token s -> Printf.sprintf "unexpected token: %s" s
129131 | Expected_document_start -> "expected document start '---'"
130132 | Expected_document_end -> "expected document end '...'"
···680680 leading_blanks := true
681681 end;
682682 Input.consume_break t.input;
683683- (* Line break allows simple key in both block and flow contexts *)
684684- if in_flow then
685685- t.allow_simple_key <- true;
686686- if not in_flow then
687687- t.allow_simple_key <- true;
683683+ (* Note: We do NOT set allow_simple_key here during plain scalar scanning.
684684+ Setting it here would incorrectly allow ':' that appears on a continuation
685685+ line to become a mapping indicator. The flag will be set properly after
686686+ the scalar ends and skip_to_next_token processes line breaks. *)
688687 (* Skip leading blanks on the next line *)
689688 while Input.next_is_blank t.input do
690689 ignore (Input.next t.input)
···718717 String.sub value 0 end_pos
719718 in
720719 let span = Span.make ~start ~stop:(Input.mark t.input) in
721721- (value, span)
720720+ (* Return value, span, and whether we ended with leading blanks (crossed a line break) *)
721721+ (value, span, !leading_blanks)
722722723723(** Scan block scalar (literal | or folded >) *)
724724let scan_block_scalar t literal =
···1189118911901190and fetch_block_entry t =
11911191 if t.flow_level = 0 then begin
11921192- (* Block entries don't require allow_simple_key to be true, because:
11931193- 1. They're not simple keys themselves
11941194- 2. They can appear after : on the same line (e.g., ": - a")
11951195- So we only check allow_simple_key in contexts where it's truly required.
11961196- For now, we allow block entries in block context. *)
11921192+ (* Block entries require allow_simple_key to be true.
11931193+ This prevents block sequences on the same line as a mapping value,
11941194+ e.g., "key: - a" is invalid. *)
11951195+ if not t.allow_simple_key then
11961196+ Error.raise_at (Input.mark t.input) Block_sequence_disallowed;
11971197 let col = column t in
11981198 if roll_indent t col ~sequence:true then begin
11991199 let span = Span.point (Input.mark t.input) in
···14351435 save_simple_key t;
14361436 t.allow_simple_key <- false;
14371437 t.document_has_content <- true;
14381438- let value, span = scan_plain_scalar t in
14381438+ let value, span, ended_with_linebreak = scan_plain_scalar t in
14391439+ (* If the plain scalar ended after crossing a line break (leading_blanks = true),
14401440+ allow simple keys. This is important because the scanner already consumed the
14411441+ line break and leading whitespace when checking for continuation. *)
14421442+ if ended_with_linebreak then
14431443+ t.allow_simple_key <- true;
14391444 emit t span (Token.Scalar { style = Scalar_style.Plain; value })
1440144514411446(** Check if we need more tokens to resolve simple keys *)