From 86d13f388fb44e6494a325944b2abd3f74139a6c Mon Sep 17 00:00:00 2001 From: JPeer264 Date: Thu, 27 Aug 2026 10:17:09 +0300 Subject: [PATCH 1/2] feat(attributes): Alias `fs_error` and `error.type` `fs_error` already replaces onto `error.type`, but neither side named the other, so the two did not form an alias group. The value changes from the full error message to the syscall error code, so the old value cannot be copied over. The deprecation therefore stays `_status: null` and keeps `error.type` as the replacement. The reason now says why the value cannot be copied. Replaced by https://github.com/getsentry/sentry-javascript/pull/23401 Co-Authored-By: Claude Opus 5 (1M context) --- .../sentry-conventions/src/attributes.ts | 23 +++++++++++++++---- model/attributes/error/error__type.json | 5 ++++ model/attributes/fs_error.json | 7 +++++- python/src/sentry_conventions/attributes.py | 10 ++++++-- 4 files changed, 38 insertions(+), 7 deletions(-) diff --git a/javascript/sentry-conventions/src/attributes.ts b/javascript/sentry-conventions/src/attributes.ts index 272b6eb64..111cc9567 100644 --- a/javascript/sentry-conventions/src/attributes.ts +++ b/javascript/sentry-conventions/src/attributes.ts @@ -6394,6 +6394,8 @@ export type ENVIRONMENT_TYPE = string; * Attribute defined in OTEL: Yes * Visibility: public * + * Aliases: {@link FS_ERROR} `fs_error` + * * @example "timeout" */ export const ERROR_TYPE = 'error.type'; @@ -7128,7 +7130,9 @@ export type FRAMES_TOTAL_TYPE = number; * Attribute defined in OTEL: No * Visibility: public * - * @deprecated Use {@link ERROR_TYPE} (error.type) instead - This attribute is not part of the OpenTelemetry specification and error.type fits much better. + * Aliases: {@link ERROR_TYPE} `error.type` + * + * @deprecated Use {@link ERROR_TYPE} (error.type) instead - This attribute is not part of the OpenTelemetry specification and error.type fits much better. The value changes from the full error message to the syscall error code, so the old value cannot be copied over. * @example "ENOENT: no such file or directory" */ export const FS_ERROR = 'fs_error'; @@ -24729,7 +24733,12 @@ export const ATTRIBUTE_METADATA: Record = { isInOtel: true, visibility: 'public', example: 'timeout', - changelog: [{ version: '0.1.0', prs: [127] }, { version: '0.0.0' }], + aliases: ['fs_error'], + changelog: [ + { version: 'next', description: 'Added fs_error as an alias' }, + { version: '0.1.0', prs: [127] }, + { version: '0.0.0' }, + ], }, 'event.id': { brief: 'The unique identifier for this event (log record)', @@ -25261,9 +25270,15 @@ export const ATTRIBUTE_METADATA: Record = { example: 'ENOENT: no such file or directory', deprecation: { replacement: 'error.type', - reason: 'This attribute is not part of the OpenTelemetry specification and error.type fits much better.', + reason: + 'This attribute is not part of the OpenTelemetry specification and error.type fits much better. The value changes from the full error message to the syscall error code, so the old value cannot be copied over.', }, - changelog: [{ version: '0.1.0', prs: [61, 127] }, { version: '0.0.0' }], + aliases: ['error.type'], + changelog: [ + { version: 'next', description: 'Added error.type as an alias' }, + { version: '0.1.0', prs: [61, 127] }, + { version: '0.0.0' }, + ], }, 'gcp.function.context.event_id': { brief: 'The event ID from the legacy GCP Cloud Function context (1st gen)', diff --git a/model/attributes/error/error__type.json b/model/attributes/error/error__type.json index 284af777a..6097c87bb 100644 --- a/model/attributes/error/error__type.json +++ b/model/attributes/error/error__type.json @@ -7,8 +7,13 @@ }, "is_in_otel": true, "example": "timeout", + "alias": ["fs_error"], "visibility": "public", "changelog": [ + { + "version": "next", + "description": "Added fs_error as an alias" + }, { "version": "0.1.0", "prs": [127] diff --git a/model/attributes/fs_error.json b/model/attributes/fs_error.json index 03335f218..a4237e989 100644 --- a/model/attributes/fs_error.json +++ b/model/attributes/fs_error.json @@ -7,13 +7,18 @@ }, "is_in_otel": false, "example": "ENOENT: no such file or directory", + "alias": ["error.type"], "deprecation": { "_status": null, "replacement": "error.type", - "reason": "This attribute is not part of the OpenTelemetry specification and error.type fits much better." + "reason": "This attribute is not part of the OpenTelemetry specification and error.type fits much better. The value changes from the full error message to the syscall error code, so the old value cannot be copied over." }, "visibility": "public", "changelog": [ + { + "version": "next", + "description": "Added error.type as an alias" + }, { "version": "0.1.0", "prs": [61, 127] diff --git a/python/src/sentry_conventions/attributes.py b/python/src/sentry_conventions/attributes.py index 4a31cdc44..4b6dc18cf 100644 --- a/python/src/sentry_conventions/attributes.py +++ b/python/src/sentry_conventions/attributes.py @@ -4005,6 +4005,7 @@ class ATTRIBUTE_NAMES(metaclass=_AttributeNamesMeta): Apply Scrubbing: manual Defined in OTEL: Yes Visibility: public + Aliases: fs_error Example: "timeout" """ @@ -4390,7 +4391,8 @@ class ATTRIBUTE_NAMES(metaclass=_AttributeNamesMeta): Apply Scrubbing: manual Defined in OTEL: No Visibility: public - DEPRECATED: Use error.type instead - This attribute is not part of the OpenTelemetry specification and error.type fits much better. + Aliases: error.type + DEPRECATED: Use error.type instead - This attribute is not part of the OpenTelemetry specification and error.type fits much better. The value changes from the full error message to the syscall error code, so the old value cannot be copied over. Example: "ENOENT: no such file or directory" """ @@ -16125,7 +16127,9 @@ class ATTRIBUTE_NAMES(metaclass=_AttributeNamesMeta): is_in_otel=True, visibility=Visibility.PUBLIC, example="timeout", + aliases=["fs_error"], changelog=[ + ChangelogEntry(version="next", description="Added fs_error as an alias"), ChangelogEntry(version="0.1.0", prs=[127]), ChangelogEntry(version="0.0.0"), ], @@ -16733,9 +16737,11 @@ class ATTRIBUTE_NAMES(metaclass=_AttributeNamesMeta): example="ENOENT: no such file or directory", deprecation=DeprecationInfo( replacement="error.type", - reason="This attribute is not part of the OpenTelemetry specification and error.type fits much better.", + reason="This attribute is not part of the OpenTelemetry specification and error.type fits much better. The value changes from the full error message to the syscall error code, so the old value cannot be copied over.", ), + aliases=["error.type"], changelog=[ + ChangelogEntry(version="next", description="Added error.type as an alias"), ChangelogEntry(version="0.1.0", prs=[61, 127]), ChangelogEntry(version="0.0.0"), ], From f120c870042064b65725f23be9322d4193c663cd Mon Sep 17 00:00:00 2001 From: JPeer264 Date: Fri, 28 Aug 2026 15:10:04 +0200 Subject: [PATCH 2/2] feat(attributes): Transform `fs_error` into `error.type` `fs_error` holds the full file system error message, for example `ENOENT: no such file or directory, open '/tmp/missing.txt'`. v11 of the JavaScript SDK reports the syscall error code on `error.type` instead, so the value has to be shortened, not just renamed. Adds the `fs_error_to_error_type` transformation and sets `fs_error` to `_status: "transform"`. No alias is added, matching how `gen_ai.request.messages` is modelled: an alias declares two names for the same value, which is no longer true once the value changes. Replaced by https://github.com/getsentry/sentry-javascript/pull/23401 Co-Authored-By: Claude Opus 5 (1M context) --- .../sentry-conventions/src/attributes.ts | 16 ++---- .../fs_error_to_error_type.json | 52 +++++++++++++++++++ model/attributes/error/error__type.json | 5 -- model/attributes/fs_error.json | 6 +-- python/src/sentry_conventions/attributes.py | 11 ++-- 5 files changed, 64 insertions(+), 26 deletions(-) create mode 100644 model/attribute_transformations/fs_error_to_error_type.json diff --git a/javascript/sentry-conventions/src/attributes.ts b/javascript/sentry-conventions/src/attributes.ts index 111cc9567..f29289560 100644 --- a/javascript/sentry-conventions/src/attributes.ts +++ b/javascript/sentry-conventions/src/attributes.ts @@ -6394,8 +6394,6 @@ export type ENVIRONMENT_TYPE = string; * Attribute defined in OTEL: Yes * Visibility: public * - * Aliases: {@link FS_ERROR} `fs_error` - * * @example "timeout" */ export const ERROR_TYPE = 'error.type'; @@ -7130,8 +7128,6 @@ export type FRAMES_TOTAL_TYPE = number; * Attribute defined in OTEL: No * Visibility: public * - * Aliases: {@link ERROR_TYPE} `error.type` - * * @deprecated Use {@link ERROR_TYPE} (error.type) instead - This attribute is not part of the OpenTelemetry specification and error.type fits much better. The value changes from the full error message to the syscall error code, so the old value cannot be copied over. * @example "ENOENT: no such file or directory" */ @@ -24733,12 +24729,7 @@ export const ATTRIBUTE_METADATA: Record = { isInOtel: true, visibility: 'public', example: 'timeout', - aliases: ['fs_error'], - changelog: [ - { version: 'next', description: 'Added fs_error as an alias' }, - { version: '0.1.0', prs: [127] }, - { version: '0.0.0' }, - ], + changelog: [{ version: '0.1.0', prs: [127] }, { version: '0.0.0' }], }, 'event.id': { brief: 'The unique identifier for this event (log record)', @@ -25272,10 +25263,11 @@ export const ATTRIBUTE_METADATA: Record = { replacement: 'error.type', reason: 'This attribute is not part of the OpenTelemetry specification and error.type fits much better. The value changes from the full error message to the syscall error code, so the old value cannot be copied over.', + status: 'transform', + transformation: 'fs_error_to_error_type', }, - aliases: ['error.type'], changelog: [ - { version: 'next', description: 'Added error.type as an alias' }, + { version: 'next', description: 'Transform fs_error into error.type' }, { version: '0.1.0', prs: [61, 127] }, { version: '0.0.0' }, ], diff --git a/model/attribute_transformations/fs_error_to_error_type.json b/model/attribute_transformations/fs_error_to_error_type.json new file mode 100644 index 000000000..fa1572bd5 --- /dev/null +++ b/model/attribute_transformations/fs_error_to_error_type.json @@ -0,0 +1,52 @@ +{ + "id": "fs_error_to_error_type", + "brief": "Transform deprecated fs_error values into the syscall error code that error.type holds.", + "inputs": [ + { + "attribute": "fs_error", + "brief": "Deprecated file system error message to transform." + } + ], + "outputs": [ + { + "attribute": "error.type", + "brief": "Class of the error, given as the syscall error code." + } + ], + "actions": [ + "If error.type is already present, keep it and do not overwrite it.", + "Read fs_error as a string.", + "Take the text before the first colon as the syscall error code.", + "Remove the surrounding whitespace from that text.", + "If the result is empty, or if the text before the first colon is not fully uppercase letters, digits and underscores, do not write error.type.", + "Write the syscall error code to error.type.", + "Remove fs_error once the deprecated attribute is normalized." + ], + "examples": [ + { + "name": "error message with a path", + "input": { + "fs_error": "ENOENT: no such file or directory, open '/tmp/missing.txt'" + }, + "output": { + "error.type": "ENOENT" + } + }, + { + "name": "error message without a path", + "input": { + "fs_error": "EACCES: permission denied" + }, + "output": { + "error.type": "EACCES" + } + }, + { + "name": "message without a syscall error code", + "input": { + "fs_error": "something went wrong" + }, + "output": {} + } + ] +} diff --git a/model/attributes/error/error__type.json b/model/attributes/error/error__type.json index 6097c87bb..284af777a 100644 --- a/model/attributes/error/error__type.json +++ b/model/attributes/error/error__type.json @@ -7,13 +7,8 @@ }, "is_in_otel": true, "example": "timeout", - "alias": ["fs_error"], "visibility": "public", "changelog": [ - { - "version": "next", - "description": "Added fs_error as an alias" - }, { "version": "0.1.0", "prs": [127] diff --git a/model/attributes/fs_error.json b/model/attributes/fs_error.json index a4237e989..3429181aa 100644 --- a/model/attributes/fs_error.json +++ b/model/attributes/fs_error.json @@ -7,17 +7,17 @@ }, "is_in_otel": false, "example": "ENOENT: no such file or directory", - "alias": ["error.type"], "deprecation": { - "_status": null, + "_status": "transform", "replacement": "error.type", + "transformation": "fs_error_to_error_type", "reason": "This attribute is not part of the OpenTelemetry specification and error.type fits much better. The value changes from the full error message to the syscall error code, so the old value cannot be copied over." }, "visibility": "public", "changelog": [ { "version": "next", - "description": "Added error.type as an alias" + "description": "Transform fs_error into error.type" }, { "version": "0.1.0", diff --git a/python/src/sentry_conventions/attributes.py b/python/src/sentry_conventions/attributes.py index 4b6dc18cf..c574ad545 100644 --- a/python/src/sentry_conventions/attributes.py +++ b/python/src/sentry_conventions/attributes.py @@ -4005,7 +4005,6 @@ class ATTRIBUTE_NAMES(metaclass=_AttributeNamesMeta): Apply Scrubbing: manual Defined in OTEL: Yes Visibility: public - Aliases: fs_error Example: "timeout" """ @@ -4391,7 +4390,6 @@ class ATTRIBUTE_NAMES(metaclass=_AttributeNamesMeta): Apply Scrubbing: manual Defined in OTEL: No Visibility: public - Aliases: error.type DEPRECATED: Use error.type instead - This attribute is not part of the OpenTelemetry specification and error.type fits much better. The value changes from the full error message to the syscall error code, so the old value cannot be copied over. Example: "ENOENT: no such file or directory" """ @@ -16127,9 +16125,7 @@ class ATTRIBUTE_NAMES(metaclass=_AttributeNamesMeta): is_in_otel=True, visibility=Visibility.PUBLIC, example="timeout", - aliases=["fs_error"], changelog=[ - ChangelogEntry(version="next", description="Added fs_error as an alias"), ChangelogEntry(version="0.1.0", prs=[127]), ChangelogEntry(version="0.0.0"), ], @@ -16738,10 +16734,13 @@ class ATTRIBUTE_NAMES(metaclass=_AttributeNamesMeta): deprecation=DeprecationInfo( replacement="error.type", reason="This attribute is not part of the OpenTelemetry specification and error.type fits much better. The value changes from the full error message to the syscall error code, so the old value cannot be copied over.", + status=DeprecationStatus.TRANSFORM, + transformation="fs_error_to_error_type", ), - aliases=["error.type"], changelog=[ - ChangelogEntry(version="next", description="Added error.type as an alias"), + ChangelogEntry( + version="next", description="Transform fs_error into error.type" + ), ChangelogEntry(version="0.1.0", prs=[61, 127]), ChangelogEntry(version="0.0.0"), ],