diff --git a/packages/cli/src/types/sentry.ts b/packages/cli/src/types/sentry.ts index 3a21f2be4..c9b9a137d 100644 --- a/packages/cli/src/types/sentry.ts +++ b/packages/cli/src/types/sentry.ts @@ -1056,7 +1056,13 @@ export type DetailedLogsResponse = InferOutput< */ export const TraceItemAttributeSchema = variant("type", [ object({ name: string(), type: literal("str"), value: string() }), - object({ name: string(), type: literal("int"), value: number() }), + // Sentry serializes int64 values as strings to avoid precision loss + // (e.g. project_id: "4508608809533441"); keep them as strings. + object({ + name: string(), + type: literal("int"), + value: union([number(), string()]), + }), object({ name: string(), type: literal("float"), value: number() }), object({ name: string(), type: literal("bool"), value: boolean() }), // "array" is gated by organizations:trace-item-details-array-fields in Sentry backend diff --git a/packages/cli/test/lib/api/traces.test.ts b/packages/cli/test/lib/api/traces.test.ts index 432ca06eb..9b6cb5ac0 100644 --- a/packages/cli/test/lib/api/traces.test.ts +++ b/packages/cli/test/lib/api/traces.test.ts @@ -731,6 +731,29 @@ describe("getSpanDetails", () => { value: "db.query", }); }); + + test("accepts int attributes serialized as strings", async () => { + mockOk({ + ...DETAIL_RESPONSE, + attributes: [ + { name: "project_id", type: "int", value: "4508608809533441" }, + { name: "retry.count", type: "int", value: 3 }, + ], + }); + + const result = await getSpanDetails( + "my-org", + "my-project", + "span-id-abc", + "trace-id-xyz", + ); + + // Strings are kept as-is so int64 IDs don't lose precision + expect(result.attributes).toEqual([ + { name: "project_id", type: "int", value: "4508608809533441" }, + { name: "retry.count", type: "int", value: 3 }, + ]); + }); }); // ---------------------------------------------------------------------------