Skip to content

serviceUrl (and other ARM-level API properties) from overrides file are silently dropped when API has a specification #141

Closed

Description

When an API has a specification file, publishRootApi() sends a single PUT containing both the override-merged properties (like serviceUrl) and spec body (properties.format + properties.value). APIM treats the spec as authoritative during import and re-derives serviceUrl from the spec's servers[0].url / host + basePath, silently discarding the override.

alignActiveRevisionWithSource() does a metadata-only re-PUT, but only fires when the API has additional revisions and is marked isCurrent, so single-revision APIs never had their overrides re-asserted.

Symptom
Given an overrides file:

apis:

and a source folder that contains both swagger-petstore/apiInformation.json and swagger-petstore/specification.yaml, running:

apiops publish --source ./artifacts --overrides ./overrides.yaml ...

Expected: destination APIM Backend → HTTP(s) endpoint = https://prod-petstore.example.com

Actual: The override is silently ignored.

Activity

  1. added
    staleNo activity for 30+ days — will be closed if no further activity
    on Aug 7, 2026
  2. github-actions commented on Aug 7, 2026

    @github-actions

    ⚠️ Stale issue notice — This issue has had no activity for 30 day(s).

    It will be automatically closed after 60 days of inactivity.

    To keep this issue open:

    • Leave a comment describing the current status, or
    • Remove the stale label.

    This notice was posted automatically by the stale issue workflow.

  3. added
    P1This sprint
    and removed
    staleNo activity for 30+ days — will be closed if no further activity
    on Aug 27, 2026
  4. github-actions commented on Sep 27, 2026

    @github-actions

    ⚠️ Stale issue notice — This issue has had no activity for 30 day(s).

    It will be automatically closed after 60 days of inactivity.

    To keep this issue open:

    • Leave a comment describing the current status, or
    • Remove the stale label.

    This notice was posted automatically by the stale issue workflow.

  5. added
    staleNo activity for 30+ days — will be closed if no further activity
    on Sep 27, 2026
  6. azaslonov commented on Oct 2, 2026

    @azaslonov
    Member

    Aleksey Zheltov (@Alexey-Zheltov) I tried to reproduce this and could not. Findings below; could you share more details on your setup?

    Code path

    publishRootApi() applies overrides before injecting the spec, then copies every non-null property (including the overridden serviceUrl) into the import PUT body alongside properties.format / properties.value. So the override is sent in the same request as the spec. This was already the case on main when the issue was opened.

    Live APIM tests (sent a serviceUrl that differs from the spec's servers[0].url / host+basePath, then read the API back)

    Scenario api-version Resulting serviceUrl
    New API, OpenAPI 3 JSON (openapi+json) 2024-06-01-preview, 2025-09-01-preview value from the PUT body
    Existing API re-PUT with spec + new serviceUrl both value from the PUT body
    Swagger 2.0 (swagger-json, host/basePath) both value from the PUT body
    OpenAPI YAML (openapi), create and update 2025-09-01-preview value from the PUT body
    New API created at apis/{name};rev=2 with spec 2025-09-01-preview value from the PUT body

    In every case APIM kept the explicit serviceUrl from the request rather than the spec's server URL.

    End-to-end CLI run

    1. apiops extract of a single API -> apiInformation.json + specification.yaml (whose servers points at the source gateway URL).
    2. apiops publish --overrides overrides.yaml with exactly the override shape from this issue:
      apis:
        - name: <api-name>
          properties:
            serviceUrl: https://prod-petstore.example.com
    3. Deployed API serviceUrl = https://prod-petstore.example.com.

    Could you share

    • The CLI version you used.
    • The override file and the API folder name under apis/ (the override name must match the API resource name / folder name, not the display name).
    • The full publish command, in particular whether --commit-id / COMMIT_ID (incremental publish) or --filter was used. If only the overrides file changed between commits, the API may not have been selected for publish at all.
    • --log-level debug output for the API, if possible.

    If there is no repro, I suggest closing this as not reproducible.

  7. Alexey-Zheltov commented on Oct 4, 2026

    @Alexey-Zheltov
    CollaboratorAuthor

    Issue was fixed in v0.2.0-alpha.0

    I traced this through main history and reproduced the scenario. The bug was in the beta I was running, but it has been fixed since v0.2.0-alpha.0 (2026-06-10) released one day before this issue was opened.

    Actual root cause

    The problem was not in publishRootApi() — the order "apply overrides → copy non-null properties → inject format/value into the same PUT" has been correct since the initial commit (d623fb7). The spec-import correlation in my original report was a red herring.

    The real bug was in the overrides file loader in 0.1.x alphas:

    • loadOverrideConfig() did a raw yaml.load() cast with no normalization or validation
    • applyOverrides() looked entries up as a map: Object.keys(overrideSection).find(key => key.toLowerCase() === apiName)
    • An overrides file in the Toolkit array format (apis: [{ name: ..., properties: ... }]) made overrideSection an array, so Object.keys() returned indices ('0', '1', …) — the API name never matched and the override was silently dropped, with no warning, for every API (with or without a specification)

    Fix timeline

    Date Commit / PR Change
    2026-06-01 7d26c67, 304e436 (#102) Align overrides to Toolkit list format — loader normalizes the array format into the internal map
    2026-06-06…08 f058d6b, 99fbd6a (#115) Full Toolkit config parity — invalid section shapes now fail loudly instead of silently no-op'ing
    2026-06-10 v0.2.0-alpha.0 First release containing the fix (changelog: "Override & filter config alignment — fully aligned with APIOps Toolkit array-based format (#102, #115)")

    Alexander Zaslonov (@azaslonov) this matches your findings. I was on a 0.1.x alpha when I filed this. Closing as fixed in v0.2.0-alpha.0.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

P1This sprintstaleNo activity for 30+ days — will be closed if no further activity

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions