dotnet/wpf · error · ArgumentException

Object identifiers must be unique within the same signature.

Error message

Object identifiers must be unique within the same signature.

What it means

VerifySignArguments enforces that DataObject Ids are unique within the signature: a duplicate Id throws ArgumentException (SR.SignatureObjectIdMustBeUnique) for the signatureObjects parameter. XML-DSig requires object IDs to be unique XML IDs within one signature document.

Solutions

  1. Give each DataObject a distinct Id (e.g. suffix with an index: obj1, obj2, ...).
  2. Deduplicate the signatureObjects collection before calling Sign (e.g. DistinctBy(o => o.Id)).
  3. Pre-validate uniqueness with a HashSet of Ids before invoking Sign.

Example fix

// before
objs.Add(new DataObject { Id = "obj1", ObjectXml = xmlA });
objs.Add(new DataObject { Id = "obj1", ObjectXml = xmlB }); // duplicate
// after
objs.Add(new DataObject { Id = "obj1", ObjectXml = xmlA });
objs.Add(new DataObject { Id = "obj2", ObjectXml = xmlB });
Defensive patterns

Strategy: validation

Validate before calling

var ids = new HashSet<string>(StringComparer.Ordinal);
foreach (var o in sigObjects ?? Enumerable.Empty<DataObject>())
    if (!ids.Add(o.Id)) throw new InvalidOperationException($"Duplicate DataObject Id: {o.Id}");

Try / catch

try { mgr.Sign(cert, parts, null, sigObjects, null); }
catch (ArgumentException ex) when (ex.ParamName == "signatureObjects") { /* dedupe ids and retry */ }

Prevention

When it happens

Trigger: Calling Sign() with two or more DataObjects sharing the same Id string in the signatureObjects collection.

Common situations: Adding the same DataObject instance twice, or generating objects in a loop with a fixed/constant Id rather than a counter.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14). Data as JSON: /api/errors/292c24a76ad9f929. Report an issue: GitHub.

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/WindowsBase/System/IO/Packaging/PackageDigitalSignatureManager.cs:964

            // Check for empty collections in order to provide negative feedback as soon as possible.
            if (EnumeratorEmptyCheck(parts) && EnumeratorEmptyCheck(relationshipSelectors)
                && EnumeratorEmptyCheck(signatureObjects) && EnumeratorEmptyCheck(objectReferences))
                throw new ArgumentException(SR.NothingToSign);

            // check for illegal and/or duplicate id's in signatureObjects
            if (signatureObjects != null)
            {
                List<String> ids = new List<String>();
                foreach (DataObject obj in signatureObjects)
                {
                    // ensure they don't duplicate the reserved one
                    if (string.Equals(obj.Id, XTable.Get(XTable.ID.OpcAttrValue), StringComparison.Ordinal))
                        throw new ArgumentException(SR.SignaturePackageObjectTagMustBeUnique, nameof(signatureObjects));

                    // check for duplicates
                    //if (ids.Contains(obj.Id))
                    if (ids.Exists(new StringMatchPredicate(obj.Id).Match))
                        throw new ArgumentException(SR.SignatureObjectIdMustBeUnique, nameof(signatureObjects));
                    else
                        ids.Add(obj.Id);
                }
            }

            // ensure id is legal Xml id
            if (!string.IsNullOrEmpty(signatureId))
            {
                try
                {
                    // An XSD ID is an NCName that is unique.
                    System.Xml.XmlConvert.VerifyNCName(signatureId);
                }
                catch (System.Xml.XmlException xmlException)
                {
                    throw new ArgumentException(SR.Format(SR.NotAValidXmlIdString, signatureId), nameof(signatureId), xmlException);
                }
            }

View on GitHub (pinned to 81131a70a4)