#4477·keploy

MockReader splits mocks.yaml on indented '---', so keploy cannot read back a file it wrote (replay session fails to start)

Author: Aditya-eddyCreated Aug 24, 2026Updated Aug 28, 2026

Summary

MockReader splits mocks.yaml on any line whose trimmed content is ---. A YAML document separator is only a separator at column 0, so an indented --- inside a block scalar is mistaken for one. The reader then hands a truncated fragment to the YAML parser and the whole test set fails to load.

The practical effect is that keploy writes a mocks.yaml it cannot read back, and the replay session never starts — so zero tests run, and (because the upload is downstream of the replay) the test set is never uploaded, which makes keploy cloud replay impossible for that recording too.

Root cause

pkg/platform/yaml/mockreader.go, readNextYAMLDocument():

go
trimmedLine := strings.TrimSpace(line)

if trimmedLine == "---" {
    if buffer.Len() == 0 {
        continue
    }
    return buffer.Bytes(), nil
}

strings.TrimSpace removes leading whitespace too, so --- (inside a body: |+ block scalar) compares equal to "---" and terminates the document.

Reproduction

Record any request whose captured body contains a line that is --- after trimming. We hit it recording an LLM-backed flow, because --- is ubiquitous in prompts, but it needs nothing exotic — markdown, YAML payloads, front-matter or an email separator will do it.

Observed with an ATG generation recording (4 test cases, 236 mocks):

ERROR utils/utils.go:314  failed to unmarshal a mock yaml doc of unknown type  {"type": ""}
ERROR utils/utils.go:314  failed to get filtered mocks
ERROR utils/utils.go:314  failed to run test set: failed to decode the file documents.
      error: failed to decode YAML at line 5480: yaml: line 8: mapping values are not allowed in this context
ERROR replay/replay.go:1515  replay session failed to start

Reproduced twice; the offset tracks the recorded content (line 5480, then 5484).

The offending mock is the outbound Azure OpenAI call:

yaml
kind: Http2
spec:
    req:
        method: POST
        url: /openai/v1/responses
        authority: keploy-llm-temp.cognitiveservices.azure.com
        body: |+
            ...
                      ---          <-- line 5449, indented, inside the block scalar
            ...
                      ---          <-- line 5475

The file itself is valid — this is reader-side only

$ python3 -c "import yaml; print(len(list(yaml.safe_load_all(open('mocks.yaml')))))"
236

yaml.safe_load_all parses all 236 documents cleanly (DNS: 8, Mongo: 222, Http2: 4, Http: 2). A conformant parser honours block-scalar indentation; only the hand-rolled line splitter does not. So the writer is fine and nothing already recorded is lost — those files become readable again as soon as the reader is fixed.

Suggested fix

Only strip trailing whitespace, so column-0 anchoring is preserved:

go
// A YAML document separator is only a separator at column 0. TrimSpace also
// removes leading whitespace, which makes an indented "---" inside a block
// scalar (e.g. a recorded body containing markdown) look like a new document.
trimmedLine := strings.TrimRight(line, " \t\r\n")

if trimmedLine == "---" {

Note trimmedLine is also used two lines below for the # comment check; that one wants a leading-trimmed value, so the two uses should be separated rather than sharing one variable.

Worth a regression test: a mock whose body is a block scalar containing an indented ---, asserted to round-trip through MockReader.

Impact

High. It is silent (nothing warns at record time), it takes out the entire test set rather than one test case, and it blocks cloud replay as a knock-on because the upload never happens. Any app whose traffic can contain a --- line is exposed, and LLM-backed flows essentially always are.

Environment

  • keploy enterprise 3.7.23 (CLI), k8s-proxy DaemonSet mode, kind cluster
  • api-server v1.8.13, recording prod/api-server