Skip to content

fix(v3): handle dot keys in flattenAttributes (#1510)#3185

Closed
deepshekhardas wants to merge 2 commits intotriggerdotdev:mainfrom
deepshekhardas:fix/dot-key-rendering-1510
Closed

fix(v3): handle dot keys in flattenAttributes (#1510)#3185
deepshekhardas wants to merge 2 commits intotriggerdotdev:mainfrom
deepshekhardas:fix/dot-key-rendering-1510

Conversation

@deepshekhardas
Copy link

Fixes #1510. Escapes dots in keys during flattening and unescapes them during unflattening.

deepshekhardas added 2 commits March 2, 2026 13:59
… name

The CommonCommandOptions schema was evaluating the default profile name
at module load time, which caused the --profile option to be ignored.
Changed to use an optional string with a .transform() to lazily
evaluate the default only when needed.

Fixes triggerdotdev#2542
@changeset-bot
Copy link

changeset-bot bot commented Mar 5, 2026

⚠️ No Changeset found

Latest commit: 926f2b1

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@github-actions
Copy link
Contributor

github-actions bot commented Mar 5, 2026

Hi @deepshekhardas, thanks for your interest in contributing!

This project requires that pull request authors are vouched, and you are not in the list of vouched users.

This PR will be closed automatically. See https://github.com/triggerdotdev/trigger.dev/blob/main/CONTRIBUTING.md for more details.

@github-actions github-actions bot closed this Mar 5, 2026
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 5, 2026

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 5b168ab8-8eae-4efd-8ac6-16c60770bfd2

📥 Commits

Reviewing files that changed from the base of the PR and between 5f359be and 926f2b1.

📒 Files selected for processing (3)
  • packages/cli-v3/src/cli/common.ts
  • packages/core/src/v3/utils/flattenAttributes.ts
  • packages/core/test/flattenAttributes.test.ts

Walkthrough

This pull request modifies the profile option handling in the CLI to use schema-level transformation instead of command-line defaults, introduces escaping mechanisms for preserving dots within object keys during attribute flattening and unflattening operations, and adds comprehensive test coverage for the new dot-escaping functionality.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@devin-ai-integration devin-ai-integration bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Devin Review found 3 potential issues.

View 2 additional findings in Devin Review.

Open in Devin Review

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🚩 Missing changeset for public package changes

Per CLAUDE.md and CONTRIBUTING.md, changes to packages under packages/ require a changeset (pnpm run changeset:add). This PR modifies packages/core and packages/cli-v3 (both public packages) but no .changeset/ file appears in the diff. This may be intentional if changesets are added separately, but it's worth confirming before merge.

Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Comment on lines +3 to +5
function escapeKey(key: string): string {
return key.replace(/\./g, "\\.");
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Incomplete escape scheme: keys containing backslashes cause incorrect unflattening (regression)

The new escapeKey only escapes dots (.\.) but does not escape existing backslash characters in keys. This means unflattenAttributes cannot distinguish between an escaped dot \. (intended as a literal dot in a key) and a literal backslash at the end of a key followed by the path separator dot. This is a regression from the old behavior.

Reproduction scenario

Consider flattenAttributes({ "a\\": { b: "value" } }) (key is literal a\):

  1. escapeKey("a\\")"a\\" (no dots, no change)
  2. Nested key b produces flattened key "a\\.b" (chars: a, , ., b)
  3. Old unflattenAttributes used split(".")["a\\", "b"] → correctly creates { "a\\": { b: "value" } }
  4. New unflattenAttributes uses split(/(?<!\\)\./) → the dot IS preceded by \, so lookbehind prevents splitting → ["a\\.b"]unescapeKey converts \. to . → incorrectly creates { "a.b": "value" }

The fix requires also escaping backslashes in escapeKey (\\\) and updating unescapeKey and the split regex accordingly.

Prompt for agents
In packages/core/src/v3/utils/flattenAttributes.ts, the escapeKey/unescapeKey functions at lines 3-9 need to handle backslash escaping in addition to dot escaping to avoid ambiguity. The fix:

1. escapeKey (line 3-5): First escape backslashes, then escape dots:
   function escapeKey(key: string): string {
     return key.replace(/\\/g, "\\\\").replace(/\./g, "\\.");
   }

2. unescapeKey (line 7-9): Reverse the escaping in opposite order:
   function unescapeKey(key: string): string {
     return key.replace(/\\\./g, ".").replace(/\\\\\\\\/g, "\\");
   }

3. The split regex at line 293 needs to be updated to split on dots preceded by an even number of backslashes (including zero). A simple negative lookbehind (?<!\\) is insufficient. Consider using a custom split function or a regex like split(/(?<!(?:^|[^\\])(?:\\\\)*\\)\./) or implement a character-by-character split function that tracks escape state.

All three changes must be coordinated. Update the tests in packages/core/test/flattenAttributes.test.ts to cover keys containing literal backslashes.
Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Comment on lines +3 to +9
function escapeKey(key: string): string {
return key.replace(/\./g, "\\.");
}

function unescapeKey(key: string): string {
return key.replace(/\\\./g, ".");
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🚩 Version mismatch risk: new flatten with old unflatten

If a newer SDK client uses the new flattenAttributes (which escapes dots in keys, e.g. "a\\.b"), but the webapp server is still running the old unflattenAttributes (which uses split(".")), the old code would split "a\\.b" into ["a\\", "b"] — creating a key a\ nested into b instead of the intended single key a.b. This creates a brief window during rolling deploys where data could be incorrectly unflattened. The impact depends on whether the SDK and webapp packages are always deployed in lockstep.

Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[TRI-4123] Logging objects with keys with periods in doesn't render properly in the UI

1 participant