Skip to content

Reproduce

Reproduce a bug from the exact flag state that was live when it happened — by a moment in time, or from a submitted bug-report fingerprint. Loglune delivers the replay source, and your SDK replays that version.

Guide: How to reproduce a bug that only happens for one customer

Reproduce at a moment in time

Pick a wall-clock instant and Loglune resolves the exact version that was live then, then delivers that replay source — the same one billed reproduction as reproducing by version.

Instant (T)
atUTC

2026-11-11T22:35:54Z

The replay source appears here once you reproduce by instant or by fingerprint.

Bug report fingerprints

Each fingerprint is one submitted bug report — the version, the opaque context, and the flag values that context saw. Reproduce one to deliver the exact version it hit.

FingerprintVersionContextValues seenSeen
ex-fp-2Version 3ctx-2b7e04checkout-v2=on2026-08-23 07:48 UTC
ex-fp-1Version 2ctx-9f3a1ccheckout-v2=off2026-08-18 13:22 UTC

CI setup

Add these files to your repository so CI replays the reproduced version. They hold no secret: the SDK key is read from the CI secret store at run time.

ci/replay.mjs

// Loglune replay-regression entrypoint (generated by Loglune).
// Pins the Ruleset version live at reproduction point T and asserts the case corpus
// still resolves as expected on the Loglune server. Exits non-zero on any regression,
// failing the CI job. Run: node ci/replay.mjs
import { readFileSync } from 'node:fs';
import { runReplayRegression } from '@loglune/sdk/ci-replay';

function required(name) {
  const value = process.env[name];
  if (!value) {
    console.error(`loglune replay: missing required env ${name}`);
    process.exit(2); // config error, distinct from a regression (exit 1)
  }
  return value;
}

const sdkKey = required('LOGLUNE_SDK_KEY');
const version = Number(required('LOGLUNE_VERSION'));
if (!Number.isInteger(version)) {
  console.error(`loglune replay: LOGLUNE_VERSION must be an integer`);
  process.exit(2);
}
// Reproduction point T (optional): seeds each case's evaluatedAt so time-dependent rules
// fire at T. Omit to let time rules fail closed.
const at = process.env['LOGLUNE_AT'] || undefined;
const baseUrl = process.env['LOGLUNE_API_URL'] || "https://loglune.com";
const casesPath = process.env['LOGLUNE_CASES'] || "ci/replay-cases.json";

const cases = JSON.parse(readFileSync(casesPath, 'utf8'));

const report = await runReplayRegression({ sdkKey, baseUrl, version, at }, cases);

for (const r of report.results) {
  if (!r.pass) {
    console.error(
      `FAIL case #${r.caseIndex} [${r.contextKey}] ${r.flagKey}: expected ${r.expectedVariationId}, got ${r.actualVariationId}`
    );
  }
}
console.log(
  `loglune replay v${report.version}: ${report.passed}/${report.total} assertions passed`
);
process.exit(report.ok ? 0 : 1);

ci/replay-cases.json

[
  {
    "context": {
      "key": "user-123",
      "attributes": {
        "plan": "pro",
        "country": "JP"
      },
      "evaluatedAt": "2026-08-27T00:00:00.000Z"
    },
    "expect": {
      "new-checkout": "on",
      "pricing-experiment": "variant-b"
    }
  }
]

.github/workflows/loglune-replay.yml

# Loglune replay regression (generated by Loglune).
# Evaluates the case corpus against a pinned Ruleset version on Loglune's production
# evaluation (POST /api/flags). Fails the check on any regression.
name: loglune-replay
on:
  pull_request:
  workflow_dispatch:
    inputs:
      version:
        description: Ruleset version live at the reproduction point T
        required: true
      at:
        description: 'Reproduction point T (ISO 8601, optional)'
        required: false
jobs:
  replay:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: '22'
      - run: npm ci
      - name: Loglune replay regression
        run: node ci/replay.mjs
        env:
          LOGLUNE_SDK_KEY: ${{ secrets.LOGLUNE_SDK_KEY }}
          LOGLUNE_VERSION: ${{ inputs.version }}
          LOGLUNE_AT: ${{ inputs.at }}

Recent reproductions · 2026-08

WhenVersionReproduction ID
2026-08-24 10:05 UTCVersion 3ex-repro-1
2026-08-22 16:40 UTCVersion 3ex-repro-2
2026-08-19 08:12 UTCVersion 2ex-repro-3

All reproductions and the change history are on Data.