{"record":{"id":"4b986b8078583cfa","repo":"Crosstalk-Solutions/project-nomad","slug":"sysbench-disk-write-benchmark-produced-no-parseabl","errorCode":null,"errorMessage":"sysbench disk-write benchmark produced no parseable MiB/s — aborting","messagePattern":"sysbench disk-write benchmark produced no parseable MiB/s — aborting","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"admin/app/services/benchmark_service.ts","lineNumber":1556,"sourceCode":"    // --file-extra-flags=direct (O_DIRECT) on the run bypasses the page cache (W4).\n    const output = await this._runSysbenchCommand([\n      'sh',\n      '-c',\n      'sysbench fileio --file-total-size=1G --file-num=4 prepare && ' +\n        'sysbench fileio --file-total-size=1G --file-num=4 --file-test-mode=seqwr --file-extra-flags=direct --time=30 run && ' +\n        'sysbench fileio --file-total-size=1G --file-num=4 cleanup',\n    ])\n\n    // Parse output - look for the Throughput section\n    const writeMatch = output.match(/written,\\s*MiB\\/s:\\s*([\\d.]+)/i)\n    const writesPerSecMatch = output.match(/writes\\/s:\\s*([\\d.]+)/i)\n\n    logger.debug(`[BenchmarkService] Disk write output parsing - written: ${writeMatch?.[1]}, writes/s: ${writesPerSecMatch?.[1]}`)\n\n    // Scored primary metric: fail loudly instead of silently scoring zero on a parse miss\n    const writeMbPerSec = writeMatch ? parseFloat(writeMatch[1]) : Number.NaN\n    if (!writeMatch || !Number.isFinite(writeMbPerSec) || writeMbPerSec <= 0) {\n      throw new Error('sysbench disk-write benchmark produced no parseable MiB/s — aborting')\n    }\n\n    return {\n      reads_per_second: 0,\n      writes_per_second: writesPerSecMatch ? parseFloat(writesPerSecMatch[1]) : 0,\n      read_mb_per_sec: 0,\n      write_mb_per_sec: writeMbPerSec,\n      total_time: 30,\n    }\n  }\n\n  /**\n   * Run a sysbench command in a Docker container\n   */\n  private async _runSysbenchCommand(cmd: string[]): Promise<string> {\n    let container: Dockerode.Container | null = null\n    try {\n      // Create container with TTY to avoid multiplexed output","sourceCodeStart":1538,"sourceCodeEnd":1574,"githubUrl":"https://github.com/Crosstalk-Solutions/project-nomad/blob/0bd1c6f4f9888d577fe232de06ac144bb8337131/admin/app/services/benchmark_service.ts#L1538-L1574","documentation":"Thrown by BenchmarkService after running a sysbench disk-write benchmark inside a container when the regex parsing of sysbench's stdout fails to extract a positive, finite MiB/s value. The code deliberately fails loudly (throwing instead of returning 0) because MiB/s is the primary scored metric, so a silent zero would corrupt benchmark scoring.","triggerScenarios":"Running the disk-write benchmark stage where sysbench output format differs from the expected 'MiB/s' regex (e.g. sysbench version differences, locale-adjusted decimal separators, output polluted by container logs/warnings), sysbench exiting before printing results, or parseFloat yielding NaN/0 because the matched group was malformed.","commonSituations":"Upgrading sysbench or the Docker image so output lines change (e.g. 'transferred (X MiB/s)' wording changes), non-English locale printing commas as decimal separators, OOM/killed container producing truncated output, or a changed block-size/files flag causing sysbench to print a different summary layout.","solutions":["Inspect the captured sysbench stdout (add a logger.debug of the raw output) and compare it against the writeMatch regex; adjust the regex to the actual format","Pin the sysbench/toolbox container image and version so output format is stable","Set LC_ALL=C (or an English locale) in the container env so number formatting is deterministic","Guard upstream: verify the sysbench command exits with code 0 before parsing, and treat non-zero exits as a distinct error","If a '0 MiB/s' result is legitimately possible in your environment, decide on an explicit floor value instead of relying on the parser to reject it"],"exampleFix":"// before\nconst writeMbPerSec = writeMatch ? parseFloat(writeMatch[1]) : Number.NaN\nif (!writeMatch || !Number.isFinite(writeMbPerSec) || writeMbPerSec <= 0) {\n  throw new Error('sysbench disk-write benchmark produced no parseable MiB/s — aborting')\n}\n\n// after\nconst writeMbPerSec = writeMatch ? Number.parseFloat(writeMatch[1].replace(',', '.')) : Number.NaN\nif (!writeMatch || !Number.isFinite(writeMbPerSec) || writeMbPerSec <= 0) {\n  logger.error(`[BenchmarkService] Unparseable sysbench output:\\n${rawOutput}`)\n  throw new Error('sysbench disk-write benchmark produced no parseable MiB/s — aborting')\n}","handlingStrategy":"validation","validationCode":"const m = /([\\d.]+)\\s*MiB\\/s/.exec(stdout)\nif (!m || !Number.isFinite(parseFloat(m[1].replace(',', '.'))) || parseFloat(m[1]) <= 0) {\n  throw new Error('Skip benchmark: sysbench output format unrecognized')\n}","typeGuard":"function hasValidWriteMiBs(stdout: string): boolean {\n  const m = /([\\d.]+)\\s*MiB\\/s/.exec(stdout)\n  return !!m && Number.isFinite(Number.parseFloat(m[1].replace(',', '.'))) && Number(m[1]) > 0\n}","tryCatchPattern":"try { runDiskWriteBenchmark() } catch (e) { if (e instanceof Error && e.message.includes('no parseable MiB/s')) { /* surface parse failure, keep prior stages' results */ } else throw e }","preventionTips":["Pin the sysbench container image version so output format is stable","Set LC_ALL=C inside the benchmark container","Log raw stdout on every parse attempt so format drift is diagnosable","Add a format smoke test that asserts the regex matches known sysbench output fixtures"],"tags":["benchmark","sysbench","docker","parsing","disk-io"],"backgroundTag":"cli-output-parsing-failed","analyzedSha":"0bd1c6f4f9888d577fe232de06ac144bb8337131","analyzedAt":"2026-08-27T05:34:15.424Z","schemaVersion":2},"datasetVersion":"2026-08-27T08:17:20.692Z"}