Skip to content

Data contract with shared-prefix count+sum and range-count indexes registers but document inserts fail #3960

Description

@thephez

A data contract can define two indexes on the same document type that share a prefix but require incompatible Drive tree wrapping:

  • [resourceId] with countable: "countable" and summable: "rating"
  • [resourceId, rating] with countable: "countable" and rangeCountable: true

The contract is accepted at registration, but inserting any document for that type fails when Drive tries to materialize the index trees.

This appears to be a contract validation gap or an unsupported Drive layout case. The bad state is reachable only after publishing the contract, and index definitions are immutable afterward.

Example Contract Shape

{
  "review": {
    "type": "object",
    "documentsMutable": true,
    "documentsKeepHistory": true,
    "canBeDeleted": false,
    "properties": {
      "resourceId": {
        "type": "string",
        "minLength": 1,
        "maxLength": 63,
        "position": 0
      },
      "rating": {
        "type": "integer",
        "minimum": 1,
        "maximum": 5,
        "position": 1
      },
      "reviewText": {
        "type": "string",
        "maxLength": 1000,
        "position": 2
      }
    },
    "required": ["$createdAt", "$updatedAt", "resourceId", "rating"],
    "additionalProperties": false,
    "indices": [
      {
        "name": "ownerAndResource",
        "unique": true,
        "properties": [{ "$ownerId": "asc" }, { "resourceId": "asc" }]
      },
      {
        "name": "ownerReviews",
        "properties": [{ "$ownerId": "asc" }, { "$updatedAt": "asc" }]
      },
      {
        "name": "resourceRatingAggregate",
        "properties": [{ "resourceId": "asc" }],
        "countable": "countable",
        "summable": "rating"
      },
      {
        "name": "resourceRatingDistribution",
        "properties": [{ "resourceId": "asc" }, { "rating": "asc" }],
        "countable": "countable",
        "rangeCountable": true
      }
    ]
  }
}

Observed Behavior

  1. Contract registration succeeds.
  2. Creating a review document fails during Drive insertion.

Reported decoded error:

storage: drive: not supported error: NotCountedOrSummed-wrapping is only supported for the six sum-bearing tree variants — see for_known_path_key_empty_not_summed_tree.

Expected Behavior

Either:

  1. Contract validation rejects this index combination before publish, or
  2. Drive supports this index layout during insert.

The current behavior is the worst case: the unsupported layout is accepted at publish time and fails later on every document write.

Root Cause Notes

DPP builds shared index levels and attaches index aggregation metadata only where each index terminates. It rejects exact duplicate index paths, but does not appear to validate cross-index aggregation compatibility for shared prefixes.

Relevant code:

  • packages/rs-dpp/src/data_contract/document_type/index_level/mod.rs
    IndexLevel::try_from_indices_v0 builds the shared prefix tree and only rejects duplicate terminal levels.
  • packages/rs-dpp/src/data_contract/document_type/index/mod.rs
    Index validation enforces local invariants like rangeCountable requiring countable.
  • packages/rs-dpp/src/data_contract/document_type/class_methods/try_from_schema/v2/mod.rs
    Summable validation checks same summable property, integer type, and required field, but not shared-prefix tree compatibility.

Drive insertion then derives this layout:

  • resourceRatingAggregate terminates at resourceId with count+sum, so the resourceId/<value> value tree is a CountSumTree.
  • resourceRatingDistribution continues below the same resourceId/<value> path.
  • Its rating property-name continuation has rangeCountable: true and no rangeSummable, so it is a ProvableCountTree.
  • Because the parent is a CountSumTree, Drive tries to wrap the child with NotCountedOrSummed.
  • NotCountedOrSummed currently accepts only sum-bearing inner tree variants, so ProvableCountTree is rejected.

Relevant Drive code:

  • packages/rs-drive/src/drive/document/insert/add_indices_for_index_level_for_contract_operations/v1/mod.rs
    Derives property_name_tree_type as ProvableCountTree for (range_countable=true, range_summable=false), then wraps child continuation trees when the parent value tree aggregates.
  • packages/rs-drive/src/fees/op.rs
    wrap_in_non_aggregated_for_parent_tree_type dispatches count+sum parents to for_known_path_key_empty_not_counted_or_summed_tree, which rejects non-sum-bearing inner tree variants with the observed error.

Test Coverage Gap

There are tests for summable indexes, range-countable/range-summable tree variants, and keep-history + summable behavior, but I could not find coverage for this specific cross-index case:

  • one index ending at prefix [a] with count+sum
  • another index continuing as [a, b] with count+rangeCountable only

A regression test should cover either the validation decision or Drive layout support:

  • If the intended behavior is rejection: schema/contract creation should reject the index pair.
  • If the intended behavior is support: Drive should successfully insert a document and materialize the expected trees.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions