Skip to content

fix: support mid-migration metadata templates#4653

Open
JakubKida wants to merge 1 commit into
masterfrom
metadata-namespace-migration-support
Open

fix: support mid-migration metadata templates#4653
JakubKida wants to merge 1 commit into
masterfrom
metadata-namespace-migration-support

Conversation

@JakubKida

@JakubKida JakubKida commented Jun 25, 2026

Copy link
Copy Markdown
Contributor

Summary by CodeRabbit

  • Bug Fixes
    • Improved template and schema matching for instances that only have a namespace, reducing lookup failures in migration/final modes.
    • Added fallback handling so templates resolve more reliably when scope information is missing.
    • Schema requests now work correctly across non-enterprise scopes instead of assuming a single fixed path.

@JakubKida JakubKida requested review from a team as code owners June 25, 2026 15:58
@coderabbitai

coderabbitai Bot commented Jun 25, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 03cb889d-7d78-458e-89a2-655b879af2e4

📥 Commits

Reviewing files that changed from the base of the PR and between c73a5f2 and c4696a8.

📒 Files selected for processing (2)
  • src/api/Metadata.js
  • src/common/types/metadata.js
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/common/types/metadata.js

Walkthrough

Metadata types now allow namespace-only instances and templates. Schema URL generation and schema fetches accept an optional scope, and template lookup falls back to namespace matching when scope is missing.

Changes

Metadata namespace and scope support

Layer / File(s) Summary
Metadata types
src/common/types/metadata.js
MetadataTemplate adds optional namespace, and MetadataInstanceV2 adds optional $namespace and optional $scope fields.
Schema URL and fetch scope
src/api/Metadata.js
getMetadataTemplateSchemaUrl and getSchemaByTemplateKey accept an optional scope, and schema requests use that scope in the URL path while cache keys still use templateKey.
Template fallback lookup
src/api/Metadata.js
getTemplateForInstance falls back to instance.$namespace when instance.$scope does not match and uses optional chaining in the enterprise-scope check.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • box/box-ui-elements#4450: Also changes src/api/Metadata.js and the getTemplateForInstance path, so it touches the same lookup logic.

Suggested reviewers

  • jfox-box
  • tjuanitas

Poem

A bunny hopped through scopes one night,
Then namespaces lit up the site.
When scope was shy, namespace stepped in,
And templates found their way again.
🐇✨

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly reflects the main change: supporting mid-migration metadata templates.
Description check ✅ Passed The description matches the repository template content, and no required sections or fields are missing.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch metadata-namespace-migration-support

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 Biome (2.5.0)
src/common/types/metadata.js

File contains syntax errors that prevent linting: Line 10: 'import type' are a TypeScript only feature. Convert your file to a TypeScript file or remove the syntax.; Line 12: type alias are a TypeScript only feature. Convert your file to a TypeScript file or remove the syntax.; Line 20: type alias are a TypeScript only feature. Convert your file to a TypeScript file or remove the syntax.; Line 31: type alias are a TypeScript only feature. Convert your file to a TypeScript file or remove the syntax.; Line 46: type alias are a TypeScript only feature. Convert your file to a TypeScript file or remove the syntax.; Line 57: type alias are a TypeScript only feature. Convert your file to a TypeScript file or remove the syntax.; Line 61: type alias are a TypeScript only feature. Convert your file to a TypeScript file or remove the syntax.; Line 69: type alias are a TypeScript only feature. Convert your file to a TypeScript file or remove the syntax.; Line 71: type alias are a TypeScript only f

... [truncated 1729 characters] ...

pe alias are a TypeScript only feature. Convert your file to a TypeScript file or remove the syntax.; Line 175: type alias are a TypeScript only feature. Convert your file to a TypeScript file or remove the syntax.; Line 182: type alias are a TypeScript only feature. Convert your file to a TypeScript file or remove the syntax.; Line 192: type alias are a TypeScript only feature. Convert your file to a TypeScript file or remove the syntax.; Line 197: type alias are a TypeScript only feature. Convert your file to a TypeScript file or remove the syntax.; Line 212: type alias are a TypeScript only feature. Convert your file to a TypeScript file or remove the syntax.; Line 224: 'export type' declarations are a TypeScript only feature. Convert your file to a TypeScript file or remove the syntax.

src/api/Metadata.js

File contains syntax errors that prevent linting: Line 7: 'import type' are a TypeScript only feature. Convert your file to a TypeScript file or remove the syntax.; Line 57: 'import type' are a TypeScript only feature. Convert your file to a TypeScript file or remove the syntax.; Line 58: 'import type' are a TypeScript only feature. Convert your file to a TypeScript file or remove the syntax.; Line 68: 'import type' are a TypeScript only feature. Convert your file to a TypeScript file or remove the syntax.; Line 69: 'import type' are a TypeScript only feature. Convert your file to a TypeScript file or remove the syntax.; Line 78: Type annotations are a TypeScript only feature. Convert your file to a TypeScript file or remove the syntax.; Line 78: return type annotation are a TypeScript only feature. Convert your file to a TypeScript file or remove the syntax.; Line 88: Type annotations are a TypeScript only feature. Convert your file to a TypeScript file or remove the syntax.; Line 88:

... [truncated 24636 characters] ...

y feature. Convert your file to a TypeScript file or remove the syntax.; Line 1638: Type annotations are a TypeScript only feature. Convert your file to a TypeScript file or remove the syntax.; Line 1639: Type annotations are a TypeScript only feature. Convert your file to a TypeScript file or remove the syntax.; Line 1640: Type annotations are a TypeScript only feature. Convert your file to a TypeScript file or remove the syntax.; Line 1641: Type annotations are a TypeScript only feature. Convert your file to a TypeScript file or remove the syntax.; Line 1642: optional parameters are a TypeScript only feature. Convert your file to a TypeScript file or remove the syntax.; Line 1642: Type annotations are a TypeScript only feature. Convert your file to a TypeScript file or remove the syntax.


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.

@coderabbitai

coderabbitai Bot commented Jun 25, 2026

Copy link
Copy Markdown
Contributor

Caution

Failed to replace (edit) comment. This is likely due to insufficient permissions or the comment being deleted.

Error details
{"name":"HttpError","status":500,"request":{"method":"PATCH","url":"https://api.github.com/repos/box/box-ui-elements/issues/comments/4801502026","headers":{"accept":"application/vnd.github.v3+json","user-agent":"octokit.js/0.0.0-development octokit-core.js/7.0.6 Node.js/24","authorization":"token [REDACTED]","content-type":"application/json; charset=utf-8"},"body":{"body":"<!-- This is an auto-generated comment: summarize by coderabbit.ai -->\n<!-- review_stack_entry_start -->\n\n[![Review Change Stack](https://storage.googleapis.com/coderabbit_public_assets/review-stack-in-coderabbit-ui.svg)](https://app.coderabbit.ai/change-stack/box/box-ui-elements/pull/4653?utm_source=github_walkthrough&utm_medium=github&utm_campaign=change_stack)\n\n<!-- review_stack_entry_end -->\n<!-- This is an auto-generated comment: review in progress by coderabbit.ai -->\n\n> [!NOTE]\n> Currently processing new changes in this PR. This may take a few minutes, please wait...\n> \n> <details>\n> <summary>⚙️ Run configuration</summary>\n> \n> **Configuration used**: Organization UI\n> \n> **Review profile**: CHILL\n> \n> **Plan**: Pro\n> \n> **Run ID**: `663bdb7e-179d-4256-a724-ff283df5d5fa`\n> \n> </details>\n> \n> <details>\n> <summary>📥 Commits</summary>\n> \n> Reviewing files that changed from the base of the PR and between 57396d82c48726c8674ca86940696070a42d3daa and 74d0d8366ffc0f85aab4d16287649b72b2f98b32.\n> \n> </details>\n> \n> <details>\n> <summary>📒 Files selected for processing (2)</summary>\n> \n> * `src/api/Metadata.js`\n> * `src/common/types/metadata.js`\n> \n> </details>\n> \n> ```ascii\n>  ________________________________________________________________________________________________________________________________________\n> < Use assertions to prevent the impossible. Assertions validate your assumptions. Use them to protect your code from an uncertain world. >\n>  ----------------------------------------------------------------------------------------------------------------------------------------\n>   \\\n>    \\   (\\__/)\n>        (•ㅅ•)\n>        /   づ\n> ```\n\n<!-- end of auto-generated comment: review in progress by coderabbit.ai -->\n\n<!-- finishing_touch_checkbox_start -->\n\n<details>\n<summary>✨ Finishing Touches</summary>\n\n<details>\n<summary>📝 Generate docstrings</summary>\n\n- [ ] <!-- {\"checkboxId\": \"7962f53c-55bc-4827-bfbf-6a18da830691\"} --> Create stacked PR\n- [ ] <!-- {\"checkboxId\": \"3e1879ae-f29b-4d0d-8e06-d12b7ba33d98\"} --> Commit on current branch\n\n</details>\n<details>\n<summary>🧪 Generate unit tests (beta)</summary>\n\n- [ ] <!-- {\"checkboxId\": \"f47ac10b-58cc-4372-a567-0e02b2c3d479\", \"radioGroupId\": \"utg-output-choice-group-unknown_comment_id\"} -->   Create PR with unit tests\n- [ ] <!-- {\"checkboxId\": \"6ba7b810-9dad-11d1-80b4-00c04fd430c8\", \"radioGroupId\": \"utg-output-choice-group-unknown_comment_id\"} -->   Commit unit tests in branch `metadata-namespace-migration-support`\n\n</details>\n\n</details>\n\n<!-- finishing_touch_checkbox_end -->\n<!-- tips_start -->\n\n---\n\nThanks for using [CodeRabbit](https://coderabbit.ai?utm_source=oss&utm_medium=github&utm_campaign=box/box-ui-elements&utm_content=4653)! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.\n\n<details>\n<summary>❤️ Share</summary>\n\n- [X](https://twitter.com/intent/tweet?text=I%20just%20used%20%40coderabbitai%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20the%20proprietary%20code.%20Check%20it%20out%3A&url=https%3A//coderabbit.ai)\n- [Mastodon](https://mastodon.social/share?text=I%20just%20used%20%40coderabbitai%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20the%20proprietary%20code.%20Check%20it%20out%3A%20https%3A%2F%2Fcoderabbit.ai)\n- [Reddit](https://www.reddit.com/submit?title=Great%20tool%20for%20code%20review%20-%20CodeRabbit&text=I%20just%20used%20CodeRabbit%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20proprietary%20code.%20Check%20it%20out%3A%20https%3A//coderabbit.ai)\n- [LinkedIn](https://www.linkedin.com/sharing/share-offsite/?url=https%3A%2F%2Fcoderabbit.ai&mini=true&title=Great%20tool%20for%20code%20review%20-%20CodeRabbit&summary=I%20just%20used%20CodeRabbit%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20proprietary%20code)\n\n</details>\n\n\n<sub>Comment `@coderabbitai help` to get the list of available commands.</sub>\n\n<!-- tips_end -->"},"request":{"retryCount":3,"signal":{},"retries":3,"retryAfter":16}}}

@JakubKida JakubKida force-pushed the metadata-namespace-migration-support branch from 74d0d83 to c73a5f2 Compare June 26, 2026 09:38

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 10

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@s.md`:
- Around line 2280-2286: The LIST Cascade Policy FINAL description is using the
wrong operation wording; update the text in the metadata cascade policies
documentation so it says listing/retrieval instead of creation. Locate the
endpoint description around the GET metadata_cascade_policies entry and replace
the misleading phrase in the final section while keeping the rest of the spec
reference intact.
- Around line 2068-2072: The GET Cascade Policy (SCOPED) description is using
the wrong action wording, referring to “creation” in a retrieval endpoint.
Update the endpoint description text in the relevant GET metadata cascade policy
entry so it clearly says retrieval/fetching instead of creation, keeping the
rest of the spec reference unchanged.
- Around line 1832-1843: The LIST Instance FINAL description includes an
irrelevant scope restriction that belongs to other operations. Update the text
in the metadata listing section so it only describes the LIST Instance behavior,
and remove the “If global is passed instead of box.metadata, returns 400”
sentence from the listing entry. Use the surrounding metadata endpoint section
and its LIST Instance heading to locate the affected copy-pasted wording.
- Around line 2229-2235: The LIST Cascade Policy migration text uses the wrong
operation wording in the endpoint description; update the copy in the metadata
cascade policies section so it says “listing” or “retrieval” instead of
“creation.” Locate the affected wording in the migration docs around the GET
metadata_cascade_policies entry and replace the misleading phrase while keeping
the rest of the spec reference unchanged.
- Around line 2185-2191: The operation description for the LIST Cascade Policy
SCOPED endpoint is incorrect because it says “creation” instead of describing a
list/retrieval action. Update the text in the metadata cascade policy section so
the wording matches the GET metadata_cascade_policies endpoint and the
surrounding “LIST Cascade Policy” context, using the relevant SCOPED entry to
locate it.
- Around line 2147-2152: The GET Cascade Policy FINAL description uses the wrong
action term, since this endpoint is for retrieval rather than creation. Update
the wording in the metadata cascade policy GET section so the sentence about
scoped and namespaced cascade policy behavior refers to retrieval or fetching,
and keep the rest of the endpoint description aligned with the GET operation
name and path.
- Around line 2103-2108: The GET Metadata Cascade Policy migration description
is using the wrong operation wording, referring to “creation” for a retrieval
endpoint. Update the text in the GET Cascade Policy section so it describes
fetching/retrieving the policy rather than creating it, keeping the rest of the
endpoint details and spec reference unchanged.
- Line 1: The PR title contains a typo: update “temolates” to “templates” in the
title text so it matches the intended wording.

In `@src/api/Metadata.js`:
- Around line 565-575: The template lookup in Metadata.js can incorrectly match
a namespace-only template when $scope is undefined because the primary
templates.find in the scope-based path matches on undefined scope and blocks the
namespace fallback. Update the template selection logic around the namespace and
scope checks so the first lookup only runs when scope is actually defined, and
let the namespace-based fallback handle namespace-only instances in
MIGRATION/FINAL mode using templateKey plus namespace.
- Around line 423-431: The schema cache in getSchemaByTemplateKey currently uses
only templateKey, which can return the wrong result when scope changes between
calls. Update the cache key generation and lookup in
Metadata.getSchemaByTemplateKey/getMetadataTemplateSchemaCacheKey so it
incorporates scope alongside templateKey, and ensure the same scope-aware key is
used for both cache.has and cache.get before calling
getMetadataTemplateSchemaUrl.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 9cbcb786-2c6b-4362-ad31-a1b633615294

📥 Commits

Reviewing files that changed from the base of the PR and between 51720a1 and c73a5f2.

📒 Files selected for processing (3)
  • s.md
  • src/api/Metadata.js
  • src/common/types/metadata.js

Comment thread s.md Outdated
@@ -0,0 +1,2390 @@
Namespaces API Specification

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Fix typo in PR title: "temolates" → "templates"

The PR title contains a typo: "temolates" should be "templates".

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@s.md` at line 1, The PR title contains a typo: update “temolates” to
“templates” in the title text so it matches the intended wording.

Comment thread s.md Outdated
Comment on lines +1832 to +1843
2.5.3 FINAL
Full URL:
GET https://api.box.com/2.0/files/{file_id}/metadata

GET https://api.box.com/2.0/folders/{folder_id}/metadata

Both scoped and namespaced instance retrieval is allowed.
If global is passed instead of box.metadata, returns 400.
See the full specs:
https://developer.box.com/reference/get-files-id-metadata
https://developer.box.com/reference/get-folders-id-metadata

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Remove irrelevant restriction from LIST Instance (FINAL)

Line 1839 states "If global is passed instead of box.metadata, returns 400" but the LIST Instance endpoint path (/files/{file_id}/metadata) does not include a scope/namespace path parameter. This appears to be a copy-paste error from GET/CREATE/UPDATE/DELETE sections.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@s.md` around lines 1832 - 1843, The LIST Instance FINAL description includes
an irrelevant scope restriction that belongs to other operations. Update the
text in the metadata listing section so it only describes the LIST Instance
behavior, and remove the “If global is passed instead of box.metadata, returns
400” sentence from the listing entry. Use the surrounding metadata endpoint
section and its LIST Instance heading to locate the affected copy-pasted
wording.

Comment thread s.md Outdated
Comment on lines +2068 to +2072
GET https://api.box.com/2.0/metadata_cascade_policies/{metadata_cascade_policy_id}

Only scoped cascade policy creation is allowed.
See the full spec https://developer.box.com/reference/get-metadata-cascade-policies-id

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Fix incorrect operation description in GET Cascade Policy (SCOPED)

Line 2070 says "Only scoped cascade policy creation is allowed" but this is the GET endpoint (3.3 GET Cascade Policy). Should be "retrieval" or similar.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@s.md` around lines 2068 - 2072, The GET Cascade Policy (SCOPED) description
is using the wrong action wording, referring to “creation” in a retrieval
endpoint. Update the endpoint description text in the relevant GET metadata
cascade policy entry so it clearly says retrieval/fetching instead of creation,
keeping the rest of the spec reference unchanged.

Comment thread s.md Outdated
Comment on lines +2103 to +2108
3.3.2 MIGRATION
Full URL:
GET https://api.box.com/2.0/metadata_cascade_policies/{metadata_cascade_policy_id}

Both scoped and namespaced cascade policy creation is allowed.
See the full spec https://developer.box.com/reference/get-metadata-cascade-policies-id

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Fix incorrect operation description in GET Cascade Policy (MIGRATION)

Line 2107 says "Both scoped and namespaced cascade policy creation is allowed" but this is the GET endpoint. Should be "retrieval" or similar.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@s.md` around lines 2103 - 2108, The GET Metadata Cascade Policy migration
description is using the wrong operation wording, referring to “creation” for a
retrieval endpoint. Update the text in the GET Cascade Policy section so it
describes fetching/retrieving the policy rather than creating it, keeping the
rest of the endpoint details and spec reference unchanged.

Comment thread s.md Outdated
Comment on lines +2147 to +2152
3.3.3 FINAL
Full URL:
GET https://api.box.com/2.0/metadata_cascade_policies/{metadata_cascade_policy_id}

Both scoped and namespaced cascade policy creation is allowed.
See the full spec https://developer.box.com/reference/get-metadata-cascade-policies-id

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Fix incorrect operation description in GET Cascade Policy (FINAL)

Line 2151 says "Both scoped and namespaced cascade policy creation is allowed" but this is the GET endpoint. Should be "retrieval" or similar.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@s.md` around lines 2147 - 2152, The GET Cascade Policy FINAL description uses
the wrong action term, since this endpoint is for retrieval rather than
creation. Update the wording in the metadata cascade policy GET section so the
sentence about scoped and namespaced cascade policy behavior refers to retrieval
or fetching, and keep the rest of the endpoint description aligned with the GET
operation name and path.

Comment thread s.md Outdated
Comment on lines +2185 to +2191
3.4.1 SCOPED
Full URL:
GET https://api.box.com/2.0/metadata_cascade_policies

Only scoped cascade policy creation is allowed.
See the full spec https://developer.box.com/reference/get-metadata-cascade-policies

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Fix incorrect operation description in LIST Cascade Policy (SCOPED)

Line 2189 says "Only scoped cascade policy creation is allowed" but this is the LIST endpoint (3.4 LIST Cascade Policy). Should be "listing" or "retrieval".

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@s.md` around lines 2185 - 2191, The operation description for the LIST
Cascade Policy SCOPED endpoint is incorrect because it says “creation” instead
of describing a list/retrieval action. Update the text in the metadata cascade
policy section so the wording matches the GET metadata_cascade_policies endpoint
and the surrounding “LIST Cascade Policy” context, using the relevant SCOPED
entry to locate it.

Comment thread s.md Outdated
Comment on lines +2229 to +2235
3.4.2 MIGRATION
Full URL:
GET https://api.box.com/2.0/metadata_cascade_policies

Both scoped and namespaced cascade policy creation is allowed.
See the full spec https://developer.box.com/reference/get-metadata-cascade-policies

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Fix incorrect operation description in LIST Cascade Policy (MIGRATION)

Line 2233 says "Both scoped and namespaced cascade policy creation is allowed" but this is the LIST endpoint. Should be "listing" or "retrieval".

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@s.md` around lines 2229 - 2235, The LIST Cascade Policy migration text uses
the wrong operation wording in the endpoint description; update the copy in the
metadata cascade policies section so it says “listing” or “retrieval” instead of
“creation.” Locate the affected wording in the migration docs around the GET
metadata_cascade_policies entry and replace the misleading phrase while keeping
the rest of the spec reference unchanged.

Comment thread s.md Outdated
Comment on lines +2280 to +2286
3.4.3 FINAL
Full URL:
GET https://api.box.com/2.0/metadata_cascade_policies

Both scoped and namespaced cascade policy creation is allowed.
See the full spec https://developer.box.com/reference/get-metadata-cascade-policies

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Fix incorrect operation description in LIST Cascade Policy (FINAL)

Line 2284 says "Both scoped and namespaced cascade policy creation is allowed" but this is the LIST endpoint. Should be "listing" or "retrieval".

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@s.md` around lines 2280 - 2286, The LIST Cascade Policy FINAL description is
using the wrong operation wording; update the text in the metadata cascade
policies documentation so it says listing/retrieval instead of creation. Locate
the endpoint description around the GET metadata_cascade_policies entry and
replace the misleading phrase in the final section while keeping the rest of the
spec reference intact.

Comment thread src/api/Metadata.js
Comment on lines +423 to +431
async getSchemaByTemplateKey(templateKey: string, scope?: string): Promise<MetadataTemplateSchemaResponse> {
const cache: APICache = this.getCache();
const key = this.getMetadataTemplateSchemaCacheKey(templateKey);

// Return cached value if it exists
if (cache.has(key)) {
return cache.get(key);
}

// Fetch from API if not cached
const url = this.getMetadataTemplateSchemaUrl(templateKey);
const url = this.getMetadataTemplateSchemaUrl(templateKey, scope);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Cache key must include scope to avoid cross-scope collisions.

getMetadataTemplateSchemaCacheKey keys solely on templateKey, but the schema URL now varies by scope. After the first fetch for a given templateKey, a subsequent call with a different scope (e.g. enterprise_123456 vs a namespace FQN) returns the wrong cached schema and never hits the scope-specific URL built on Line 431. This is exactly the MIGRATION/FINAL multi-scope scenario this PR targets.

Proposed fix
-    getMetadataTemplateSchemaCacheKey(templateKey: string): string {
-        return `${CACHE_PREFIX_METADATA}template_schema_${templateKey}`;
+    getMetadataTemplateSchemaCacheKey(templateKey: string, scope?: string = METADATA_SCOPE_ENTERPRISE): string {
+        return `${CACHE_PREFIX_METADATA}template_schema_${scope}_${templateKey}`;
     }
-        const key = this.getMetadataTemplateSchemaCacheKey(templateKey);
+        const key = this.getMetadataTemplateSchemaCacheKey(templateKey, scope);
🧰 Tools
🪛 Biome (2.5.0)

[error] 423-423: Type annotations are a TypeScript only feature. Convert your file to a TypeScript file or remove the syntax.

(parse)


[error] 423-423: optional parameters are a TypeScript only feature. Convert your file to a TypeScript file or remove the syntax.

(parse)


[error] 423-423: Type annotations are a TypeScript only feature. Convert your file to a TypeScript file or remove the syntax.

(parse)


[error] 423-423: return type annotation are a TypeScript only feature. Convert your file to a TypeScript file or remove the syntax.

(parse)


[error] 424-424: type annotation are a TypeScript only feature. Convert your file to a TypeScript file or remove the syntax.

(parse)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/api/Metadata.js` around lines 423 - 431, The schema cache in
getSchemaByTemplateKey currently uses only templateKey, which can return the
wrong result when scope changes between calls. Update the cache key generation
and lookup in Metadata.getSchemaByTemplateKey/getMetadataTemplateSchemaCacheKey
so it incorporates scope alongside templateKey, and ensure the same scope-aware
key is used for both cache.has and cache.get before calling
getMetadataTemplateSchemaUrl.

Comment thread src/api/Metadata.js
Comment on lines +565 to +575
const namespace = instance.$namespace;

// Primary match: by scope (SCOPED mode; also works for enterprise-scoped
// instances in MIGRATION mode where $scope is still populated).
let template = templates.find(t => t.templateKey === templateKey && t.scope === scope);

// Fallback match: by namespace for namespace-only instances in
// MIGRATION/FINAL mode where $scope is absent.
if (!template && namespace) {
template = templates.find(t => t.templateKey === templateKey && t.namespace === namespace);
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Confirm how `scope` is derived in getTemplateForInstance (definition not shown)
rg -nP --type=js -C3 'getTemplateForInstance' src/api/Metadata.js

Repository: box/box-ui-elements

Length of output: 1191


🏁 Script executed:

sed -n '557,600p' src/api/Metadata.js

Repository: box/box-ui-elements

Length of output: 2389


Primary scope match can short-circuit the namespace fallback when $scope is absent.

For namespace-only instances, scope is undefined. The primary match t.scope === scope succeeds for any template with undefined scope, selecting purely by templateKey and ignoring namespace. When multiple namespace-only templates share a templateKey across different namespaces, the wrong template is chosen and the namespace fallback never executes.

Gate the primary match on a defined scope to ensure the namespace fallback runs correctly:

Proposed fix
-        let template = templates.find(t => t.templateKey === templateKey && t.scope === scope);
+        let template = scope
+            ? templates.find(t => t.templateKey === templateKey && t.scope === scope)
+            : undefined;
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const namespace = instance.$namespace;
// Primary match: by scope (SCOPED mode; also works for enterprise-scoped
// instances in MIGRATION mode where $scope is still populated).
let template = templates.find(t => t.templateKey === templateKey && t.scope === scope);
// Fallback match: by namespace for namespace-only instances in
// MIGRATION/FINAL mode where $scope is absent.
if (!template && namespace) {
template = templates.find(t => t.templateKey === templateKey && t.namespace === namespace);
}
const namespace = instance.$namespace;
// Primary match: by scope (SCOPED mode; also works for enterprise-scoped
// instances in MIGRATION mode where $scope is still populated).
let template = scope
? templates.find(t => t.templateKey === templateKey && t.scope === scope)
: undefined;
// Fallback match: by namespace for namespace-only instances in
// MIGRATION/FINAL mode where $scope is absent.
if (!template && namespace) {
template = templates.find(t => t.templateKey === templateKey && t.namespace === namespace);
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/api/Metadata.js` around lines 565 - 575, The template lookup in
Metadata.js can incorrectly match a namespace-only template when $scope is
undefined because the primary templates.find in the scope-based path matches on
undefined scope and blocks the namespace fallback. Update the template selection
logic around the namespace and scope checks so the first lookup only runs when
scope is actually defined, and let the namespace-based fallback handle
namespace-only instances in MIGRATION/FINAL mode using templateKey plus
namespace.

@JakubKida JakubKida force-pushed the metadata-namespace-migration-support branch from c73a5f2 to c4696a8 Compare June 26, 2026 09:48
@CLAassistant

Copy link
Copy Markdown

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.


Jakub Kida seems not to be a GitHub user. You need a GitHub account to be able to sign the CLA. If you have already a GitHub account, please add the email address used for this commit to your account.
You have signed the CLA already but the status is still pending? Let us recheck it.

@JakubKida JakubKida changed the title fix: support mid-migration metadata temolates fix: support mid-migration metadata templates Jun 26, 2026
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.

2 participants