[BUG]: Profile deploy/convert moves root `xmlns:*` declarations into a `<@_xmlns:…>` child element (SDR 13.8.3+)

クローズ
#3,677 コメント 1 件 リアクション 0 件 担当者 0 名 GitHub で見る

関連するプルリクエストがすでにマージされています。

  • #1865 @WillieRuemmele による — マージ済み

評価

難易度
4/5
見積もり時間
3〜5日
初心者へのやさしさ
35/100
issue の種類
バグ
明瞭さ
明確に書かれている
活発さ
活発
技術スタック
node.js, typescript, xml
領域
cli, tooling

調査の方向性

The payload points to mergeProfiles() in src/convert/convertContext/profileMetadataFinalizer.ts, which lives in the source-deploy-retrieve repository, not this one. Start by reproducing with the two sample Profile files and sf project convert source --metadata Profile, then check where root @_xmlns:* keys are treated as child tags. Done means the root <Profile> keeps its xmlns:xsi declaration and the converted output matches the expected XML.

索引モデルが issue の本文から書いたものです。

説明

regression
Before You Submit
  • I'm using the latest version of Salesforce CLI
  • I've searched the existing issues
  • I've run sf doctor to diagnose common issues
Related Issue

No response

Command

sf project deploy start

Org Type

Sandbox

Did this work before?

Yes, this is a regression

Last Working Version

2.156.0

Summary

Since @salesforce/source-deploy-retrieve 13.8.3, every Profile is converted through the new ProfileMetadataFinalizer. When the root <Profile> element declares a namespace besides the default one (for example xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance", used by xsi:nil), that declaration is removed from the root and written as a child element named <@_xmlns:xsi>. The org then rejects the file with "Error parsing file". Any Profile carrying such a declaration now fails to deploy.

Repository to Reproduce

No response

Steps to reproduce
  1. In any Salesforce DX project, create force-app/main/default/profiles/UsesNs.profile-meta.xml:
    <?xml version="1.0" encoding="UTF-8"?>
    <Profile xmlns="http://soap.sforce.com/2006/04/metadata" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
        <custom>true</custom>
        <description xsi:nil="true"/>
        <userLicense>Salesforce</userLicense>
    </Profile>
    
  2. Create force-app/main/default/profiles/DeclaresNs.profile-meta.xml:
    <?xml version="1.0" encoding="UTF-8"?>
    <Profile xmlns="http://soap.sforce.com/2006/04/metadata" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
        <custom>true</custom>
        <description>Declares xsi but does not use it</description>
        <userLicense>Salesforce</userLicense>
    </Profile>
    
  3. Run sf project convert source --metadata Profile --output-dir out and inspect out/profiles/*.profile.
  4. Or run sf project deploy start --dry-run --source-dir force-app -o <sandbox>.
Expected Result

The xmlns:xsi declaration stays on the root <Profile> element, as it did up to CLI 2.156.0 / SDR 13.4.6:

<Profile xmlns="http://soap.sforce.com/2006/04/metadata" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <custom>true</custom>
    <description xsi:nil="true"/>
    <userLicense>Salesforce</userLicense>
</Profile>

On 2.156.0, the dry-run deploy succeeds.

Actual Result

The declaration is dropped from the root and appended as a child element (the output of convert source is identical to what deploy start sends; you can confirm with SF_MDAPI_TEMP_DIR):

<Profile xmlns="http://soap.sforce.com/2006/04/metadata">
    <custom>true</custom>
    <description xsi:nil="true"></description>
    <userLicense>Salesforce</userLicense>
    <@_xmlns:xsi>http://www.w3.org/2001/XMLSchema-instance</@_xmlns:xsi>
</Profile>

The deploy fails for both profiles. This happens over both SOAP and REST (SF_ORG_METADATA_REST_DEPLOY=true).

Error Message
DeclaresNs  Error parsing file: The content of elements must consist of well-formed character data or markup.
UsesNs      Error parsing file: The prefix "xsi" for attribute "xsi:nil" associated with an element type "description" is not bound.
System Information
{
  "architecture": "darwin-arm64",
  "cliVersion": "@salesforce/cli/2.156.8",
  "nodeVersion": "node-v24.14.1",
  "osVersion": "Darwin 24.6.0",
  "rootPath": "<npm global>/node_modules/@salesforce/cli",
  "pluginVersions": [
    "@oclif/plugin-autocomplete 4.0.5 (core)",
    "@oclif/plugin-commands 5.0.5 (core)",
    "@oclif/plugin-help 7.0.5 (core)",
    "@oclif/plugin-not-found 4.0.5 (core)",
    "@oclif/plugin-plugins 7.0.10 (core)",
    "@oclif/plugin-search 2.0.5 (core)",
    "@oclif/plugin-update 5.0.8 (core)",
    "@oclif/plugin-version 3.0.6 (core)",
    "@oclif/plugin-warn-if-update-available 4.0.4 (core)",
    "@oclif/plugin-which 4.0.5 (core)",
    "@salesforce/cli 2.156.8 (core)",
    "agent 2.2.3 (core)",
    "apex 4.4.4 (core)",
    "api 2.0.19 (core)",
    "auth 6.0.0 (core)",
    "data 5.1.19 (core)",
    "deploy-retrieve 4.2.18 (core)",
    "info 4.0.18 (core)",
    "limits 4.0.6 (core)",
    "marketplace 2.0.18 (core)",
    "org 7.0.2 (core)",
    "packaging 3.0.14 (core)",
    "schema 4.0.12 (core)",
    "settings 3.0.17 (core)",
    "sobject 2.0.13 (core)",
    "telemetry 4.2.1 (core)",
    "templates 57.4.8 (core)",
    "trust 4.0.23 (core)",
    "user 6.0.3 (core)"
  ],
  "shell": "zsh"
}
Additional Information

Resolved @salesforce/source-deploy-retrieve: 13.10.0. The same failure occurs on linux-x64 / node 24.22.2 with deploy-retrieve 4.2.24 installed as a user plugin (the hardisgroupcom/sfdx-hardis-ubuntu CI image).

Cause: mergeProfiles() in src/convert/convertContext/profileMetadataFinalizer.ts, added in forcedotcom/source-deploy-retrieve#1854:

const merged: JsonMap = { [XML_NS_KEY]: XML_NS_URL };
...
if (key === XML_NS_KEY || value === undefined) continue;

Only @_xmlns is treated as a root attribute. Every other root attribute key (@_xmlns:xsi, @_xmlns:n1, …) goes through the merge loop like a child tag. It is collected into an array, and JsToXml serialises arrays as repeated child elements, so the result is <@_xmlns:xsi>…</@_xmlns:xsi>. Nested attributes such as xsi:nil survive because they sit inside a child object, which is why the prefix ends up unbound. The source-side merge path in finalize() (profile: { [XML_NS_KEY]: XML_NS_URL } plus the same XML_NS_KEY skip) looks to have the same problem. I didn't test that path.

Suggested fix: treat every key starting with the attribute prefix (@_) on the root Profile object as a root attribute: copy it to the merged output once, without merging it as a child.

Why "Last Working Version" is 2.156.0: from 2.156.1 onward, @salesforce/cli no longer publishes an npm-shrinkwrap.json. A fresh install of any later CLI therefore resolves the latest SDR (currently 13.10.0), even though deploy-retrieve 4.2.18 only requires ^13.4.6.

Workarounds:

  • Install @salesforce/[email protected], and remove any user-installed @salesforce/plugin-deploy-retrieve so that the core plugin is used.
  • Or strip the extra namespace declarations (and the xsi:nil elements) from Profiles before deploying.
Screenshots or Log Files

No response

主要言語
言語のデータがありません
スター
575
フォーク
80
平均マージ
11時間 37分
マージ済み PR(30日)
6

環境構築

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

forcedotcom/cli のほかの issue

forcedotcom/cli の issue をすべて見る

似ている issue

CLI の issue をもっと見る

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。