Skip to content

Bug: Duplicate ordId generated for multi-protocol services #397

@zongqichen

Description

@zongqichen

Description

When a CDS service declares multiple protocols (e.g., @protocol: ['odata-v4', 'rest'] or @protocol: ['odata-v4', 'mcp']), the plugin generates multiple apiResource entries with the same ordId, violating the ORD spec's uniqueness requirement.

Root Cause

PR #370 (fix: detect multi-protocol services) updated protocol-resolver.js to return all protocols instead of just the first one. However, templates.js was not updated — the ordId is computed outside the protocolResults.forEach() loop at line 325:

const ordId = `${appConfig.ordNamespace}:apiResource:${cleanServiceName}:${version}`;

protocolResults.forEach((protocolResult) => {
    const { apiProtocol, entryPoints, hasResourceDefinitions } = protocolResult;
    // ...
    let obj = { ordId, apiProtocol, ... };  // same ordId for every protocol
    apiResources.push(obj);
});

Why the plugin's own tests didn't catch it

  1. Bookshop test model has no multi-protocol services — all services use default single protocol (OData), so the duplicate ordId path is never exercised
  2. E2e tests actively filter out MCP — assertions use .filter((r) => r.apiProtocol !== "mcp"), so MCP apiResources are excluded from validation
  3. Snapshot tests don't verify ordId uniqueness — snapshots match structure but don't enforce semantic constraints like document-wide ordId uniqueness
  4. PR fix: detect multi-protocol services #370 only added unit tests for protocol-resolver.js — verified that multiple protocols are returned correctly, but no integration test verified that the generated ORD document is valid

This bug was discovered by an e2e pipeline that compiles real multi-protocol services and validates the generated ORD documents with the api-metadata-validator.

Reproduction

@protocol: ['odata-v4', 'rest']
service TestService {
    entity Items { key ID: UUID; name: String; }
}

Generated ORD document:

[0] ordId: test:apiResource:TestService:v1  apiProtocol: odata-v4
[1] ordId: test:apiResource:TestService:v1  apiProtocol: rest       ← duplicate

This is not MCP-specific — any multi-protocol combination triggers it. Verified with both odata-v4 + rest and odata-v4 + mcp.

Impact

  • ORD documents fail validation (duplicate ordId error)
  • Affects any app using @protocol arrays with @cap-js/ord

Environment

  • @cap-js/ord: 1.5.0
  • @sap/cds: 9.8.3

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions