From 98d136bfc4e0d82f360802c48c650e651a8cdf28 Mon Sep 17 00:00:00 2001 From: Karl Rister Date: Sat, 27 Jun 2026 10:03:42 -0500 Subject: [PATCH 1/7] fix: add missing await on esJsonArrRequest() calls in getIters() Four calls to the async esJsonArrRequest() were missing await, causing .forEach() to be called on a Promise (silently failing). Two of these also used the obsolete sync-request .getBody() pattern which is incompatible with the async version. Co-Authored-By: Claude Opus 4.6 (1M context) --- queries/cdmq/cdm.js | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/queries/cdmq/cdm.js b/queries/cdmq/cdm.js index 2ed2b64e..a4089e72 100644 --- a/queries/cdmq/cdm.js +++ b/queries/cdmq/cdm.js @@ -2314,7 +2314,7 @@ getIters = async function ( }); if (jsonArr.length > 0) { - var responses = esJsonArrRequest(instance, 'tag', '/_msearch', jsonArr); + var responses = await esJsonArrRequest(instance, 'tag', '/_msearch', jsonArr); var runIds = []; responses.forEach((response) => { var theseRunIds = []; @@ -2326,7 +2326,7 @@ getIters = async function ( var intersectedRunIds = intersectAllArrays(runIds); if (jsonArr2.length > 0) { - var responses2 = esJsonArrRequest(instance, 'tag', '/_msearch', jsonArr2); + var responses2 = await esJsonArrRequest(instance, 'tag', '/_msearch', jsonArr2); responses2.forEach((response) => { response.hits.hits.forEach((run) => { if (intersectedRunIds.includes(run._source.run['run-uuid'])) { @@ -2378,8 +2378,7 @@ getIters = async function ( var iterIdsFromParam = []; if (jsonArr.length > 0) { - var resp = esJsonArrRequest(instance, 'param', '/_msearch', jsonArr); - var responses = JSON.parse(resp.getBody()); + var responses = await esJsonArrRequest(instance, 'param', '/_msearch', jsonArr); var iterationIds = []; responses.forEach((response) => { var theseIterationIds = []; @@ -2391,8 +2390,7 @@ getIters = async function ( iterIdsFromParam = intersectAllArrays(iterationIds); if (jsonArr2 != '') { - var resp2 = esJsonArrRequest(instance, 'tag', '/_msearch', jsonArr2); - var responses2 = JSON.parse(resp2.getBody()); + var responses2 = await esJsonArrRequest(instance, 'tag', '/_msearch', jsonArr2); responses2.forEach((response) => { response.hits.hits.forEach((hit) => { if (iterIdsFromParam.includes(hit._source.iteration['iteration-uuid'])) { From 4e74c4d8e49ef847a12f1cfaa62a75a69ff2f555 Mon Sep 17 00:00:00 2001 From: Karl Rister Date: Sat, 27 Jun 2026 10:04:12 -0500 Subject: [PATCH 2/7] fix: correct JSON.stringify argument order JSON.stringify(obj.null, 2) accessed obj.null (undefined) and passed 2 as the replacer. Should be JSON.stringify(obj, null, 2) to pretty-print the object with 2-space indentation. Co-Authored-By: Claude Opus 4.6 (1M context) --- queries/cdmq/cdm.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/queries/cdmq/cdm.js b/queries/cdmq/cdm.js index a4089e72..3e17a43c 100644 --- a/queries/cdmq/cdm.js +++ b/queries/cdmq/cdm.js @@ -1029,7 +1029,7 @@ mSearch = async function (instance, index, yearDotMonth, termKeys, values, sourc console.log( 'WARNING: the requested source for this query [' + source + '] does not exist in the returned data:\n' ); - console.log(JSON.stringify(obj.null, 2)); + console.log(JSON.stringify(obj, null, 2)); return; } obj = obj[thisObj]; From 6eb6c05a0c8ccf6359143a6821221fe37b6fbcd3 Mon Sep 17 00:00:00 2001 From: Karl Rister Date: Sat, 27 Jun 2026 10:04:39 -0500 Subject: [PATCH 3/7] =?UTF-8?q?fix:=20retMag=20typo=20=E2=80=94=20error=20?= =?UTF-8?q?message=20assigned=20to=20throwaway=20variable?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit retMag (typo) was assigned instead of retMsg, so the error message was lost and retMsg remained empty on return. Co-Authored-By: Claude Opus 4.6 (1M context) --- queries/cdmq/cdm.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/queries/cdmq/cdm.js b/queries/cdmq/cdm.js index 3e17a43c..3c522cda 100644 --- a/queries/cdmq/cdm.js +++ b/queries/cdmq/cdm.js @@ -3540,7 +3540,7 @@ getMetricDataSets = async function (instance, sets, yearDotMonth) { } sets[i].end = periodRange.end; } else { - retMag = 'ERROR: end is not defined or a period was not defined'; + retMsg = 'ERROR: end is not defined or a period was not defined'; retCode = 2; return { 'data-sets': [], 'ret-code': retCode, 'ret-msg': retMsg }; } From c5d0386c65108d84c17d6695dd82f9affd4e3b5c Mon Sep 17 00:00:00 2001 From: Karl Rister Date: Sat, 27 Jun 2026 10:05:09 -0500 Subject: [PATCH 4/7] fix: check addIterations instead of addRuns in iteration filter Copy-paste error: the addIterations block checked addRuns != [] instead of addIterations != [], so addIterations was only processed when addRuns was also non-empty. Co-Authored-By: Claude Opus 4.6 (1M context) --- queries/cdmq/cdm.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/queries/cdmq/cdm.js b/queries/cdmq/cdm.js index 3c522cda..4520b948 100644 --- a/queries/cdmq/cdm.js +++ b/queries/cdmq/cdm.js @@ -2435,7 +2435,7 @@ getIters = async function ( } }); } - if (isDefined(addIterations) && addRuns != []) { + if (isDefined(addIterations) && addIterations != []) { addIterations.forEach((id) => { if (!allIterIds.includes(id)) { allIterIds.push(id); From 3279c1841f0ffc1a93bc8e7db1d1c79706d76c5b Mon Sep 17 00:00:00 2001 From: Karl Rister Date: Sat, 27 Jun 2026 10:05:40 -0500 Subject: [PATCH 5/7] fix: remove line that overwrites detailed error with generic message The detailed mismatch error (response count vs request count) was immediately overwritten by an unrelated generic error about missing period-id/run-id. Remove the erroneous overwrite. Co-Authored-By: Claude Opus 4.6 (1M context) --- queries/cdmq/cdm.js | 1 - 1 file changed, 1 deletion(-) diff --git a/queries/cdmq/cdm.js b/queries/cdmq/cdm.js index 4520b948..ef1d3ed0 100644 --- a/queries/cdmq/cdm.js +++ b/queries/cdmq/cdm.js @@ -2896,7 +2896,6 @@ mgetMetricIdsFromTerms = async function (instance, termsSets, yearDotMonth) { ') did not match number of requests (' + totalReqs + ')'; - retMsg = 'ERROR: mgetMetricIdsFromTerms(), terms[' + i + '] must have either a period-id or run-id'; retCode = 2; return { 'metric-id-sets': metricIdsSets, 'ret-code': retCode, 'ret-msg': retMsg }; } From ced0adcac3f7ba64a570929ccab94212349a4cf7 Mon Sep 17 00:00:00 2001 From: Karl Rister Date: Sat, 27 Jun 2026 10:06:09 -0500 Subject: [PATCH 6/7] fix: use isDefined() instead of comparing against string 'undefined' Comparing sets[i].breakout != 'undefined' checks against the literal string, not the undefined type. When breakout is actually undefined, the comparison is true (different types), causing .length to be called on undefined (TypeError). Use the existing isDefined() helper which does typeof correctly. Co-Authored-By: Claude Opus 4.6 (1M context) --- queries/cdmq/cdm.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/queries/cdmq/cdm.js b/queries/cdmq/cdm.js index ef1d3ed0..7b05a11f 100644 --- a/queries/cdmq/cdm.js +++ b/queries/cdmq/cdm.js @@ -3605,7 +3605,7 @@ getMetricDataSets = async function (instance, sets, yearDotMonth) { // Ensure that any breakouts are available for each set for (var i = 0; i < sets.length; i++) { - if (sets[i].breakout != 'undefined') { + if (isDefined(sets[i].breakout)) { for (var j = 0; j < sets[i].breakout.length; j++) { var breakout = parseBreakoutEntry(sets[i].breakout[j]).name; if (!setBreakouts[i].includes(breakout)) { From 2fa3f7e811bd9e2d0e4387e36ee2db0c210b671b Mon Sep 17 00:00:00 2001 From: Karl Rister Date: Sat, 27 Jun 2026 10:06:34 -0500 Subject: [PATCH 7/7] fix: add var declaration to prevent implicit global race condition metric_data was assigned without var/let/const, creating an implicit global variable. Concurrent requests to /api/v1/metric-data could overwrite each other's data, returning wrong results. Add var to make it function-scoped. Co-Authored-By: Claude Opus 4.6 (1M context) --- queries/cdmq/server.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/queries/cdmq/server.js b/queries/cdmq/server.js index ad9defaf..6e492fa6 100755 --- a/queries/cdmq/server.js +++ b/queries/cdmq/server.js @@ -1637,7 +1637,7 @@ app.post('/api/v1/metric-data', async (req, res) => { error: resp['ret-msg'] }); } - metric_data = resp['data-sets'][0]; + var metric_data = resp['data-sets'][0]; var labelCount = metric_data && metric_data.values ? Object.keys(metric_data.values).length : 0; var elapsed = Date.now() - reqStart;