Expected Behavior
The library should prevent collisions between dimension keys, metric names, and metadata keys since they all share the same top-level namespace in the EMF JSON. Per the EMF spec, dimension targets MUST be strings and metric targets MUST be numbers — they cannot coexist under the same key.
Current Behavior
In serializeMetrics() at Metrics.ts:747-769, the EMF output is constructed by spreading objects in this order:
return {
_aws: { ... },
...defaultDimensions, // 1st
...dimensions, // 2nd
...dimensionSetsFlat, // 3rd
...metricValues, // 4th — overwrites dimensions
...this.#metadataStore.getAll(), // 5th — overwrites metrics
};
Since these keys share the same namespace, collisions can silently corrupt the output:
- A metric named
environment overwrites a dimension environment: 'prod' with a number — CloudWatch silently loses the dimension.
- Metadata with key
request_count overwrites a metric request_count: 42 with a string — CloudWatch fails to parse the metric.
Code snippet
import { Metrics, MetricUnit } from '@aws-lambda-powertools/metrics';
const metrics = new Metrics({ namespace: 'test' });
// Problem 1: metric overwrites dimension
metrics.addDimension('environment', 'prod');
metrics.addMetric('environment', MetricUnit.Count, 1);
const output1 = metrics.serializeMetrics();
console.log(output1.environment);
// ❌ Outputs: 1 (number) — the dimension string 'prod' was silently overwritten
// Problem 2: metadata overwrites metric
const metrics2 = new Metrics({ namespace: 'test' });
metrics2.addMetric('request_count', MetricUnit.Count, 42);
metrics2.addMetadata('request_count', 'not-a-number');
const output2 = metrics2.serializeMetrics();
console.log(output2.request_count);
// ❌ Outputs: 'not-a-number' (string) — the numeric metric value 42 was overwritten
Steps to Reproduce
Metric overwrites dimension:
- Create a
Metrics instance
- Add a dimension
environment: 'prod'
- Add a metric named
environment
- Call
serializeMetrics() — output.environment is 1, not 'prod'
Metadata overwrites metric:
- Create a
Metrics instance
- Add a metric
request_count with value 42
- Add metadata with key
request_count
- Call
serializeMetrics() — output.request_count is 'not-a-number', not 42
Possible Solution
Maintain a Set of reserved keys and check against it in storeMetric() and addMetadata():
// In storeMetric():
const dimensionKeys = new Set([
...Object.keys(this.#dimensionsStore.getDimensions()),
...Object.keys(this.#dimensionsStore.getDefaultDimensions()),
]);
if (dimensionKeys.has(name)) {
throw new Error(`Metric name "${name}" conflicts with an existing dimension key`);
}
// In addMetadata():
if (this.#metricsStore.getMetric(key) !== undefined) {
throw new Error(`Metadata key "${key}" conflicts with an existing metric name`);
}
Powertools for AWS Lambda (TypeScript) version
2.33.0
AWS Lambda function runtime
22.x
Packaging format used
npm
Disclaimer: After creating an issue, please wait until it is triaged and confirmed by a maintainer before implementing it. This will reduce amount of rework and the chance that a pull request gets rejected.
Expected Behavior
The library should prevent collisions between dimension keys, metric names, and metadata keys since they all share the same top-level namespace in the EMF JSON. Per the EMF spec, dimension targets MUST be strings and metric targets MUST be numbers — they cannot coexist under the same key.
Current Behavior
In
serializeMetrics()atMetrics.ts:747-769, the EMF output is constructed by spreading objects in this order:Since these keys share the same namespace, collisions can silently corrupt the output:
environmentoverwrites a dimensionenvironment: 'prod'with a number — CloudWatch silently loses the dimension.request_countoverwrites a metricrequest_count: 42with a string — CloudWatch fails to parse the metric.Code snippet
Steps to Reproduce
Metric overwrites dimension:
Metricsinstanceenvironment: 'prod'environmentserializeMetrics()—output.environmentis1, not'prod'Metadata overwrites metric:
Metricsinstancerequest_countwith value42request_countserializeMetrics()—output.request_countis'not-a-number', not42Possible Solution
Maintain a
Setof reserved keys and check against it instoreMetric()andaddMetadata():Powertools for AWS Lambda (TypeScript) version
2.33.0
AWS Lambda function runtime
22.x
Packaging format used
npm
Disclaimer: After creating an issue, please wait until it is triaged and confirmed by a maintainer before implementing it. This will reduce amount of rework and the chance that a pull request gets rejected.