@@ -19,6 +19,7 @@ import { isAutoGeneratedId } from '../lib/auto-generated.js';
1919import { isWorkspaceScope , buildLinkPayload } from '../lib/workspace-link.js' ;
2020import { logger } from '../lib/logger.js' ;
2121import { REDACTION_MARKER } from './secret-redactor.js' ;
22+ import { isLinkAlreadyExistsError } from '../clients/apim-client.js' ;
2223import type { OverrideConfig } from '../models/config.js' ;
2324
2425export interface ResourcePublishResult {
@@ -308,8 +309,15 @@ async function publishAssociation(
308309 type : descriptor . type ,
309310 nameParts : [ getNamePart ( descriptor . nameParts , 0 ) , entry . name ] ,
310311 } ;
311- // PUT empty body for association (APIM uses PUT to create association)
312- await client . putResource ( context , assocDescriptor , { } ) ;
312+ try {
313+ // PUT empty body for association (APIM uses PUT to create association)
314+ await client . putResource ( context , assocDescriptor , { } ) ;
315+ } catch ( error ) {
316+ // 409 means the link already exists — desired state is in place.
317+ if ( ! isLinkAlreadyExistsError ( error ) ) {
318+ throw error ;
319+ }
320+ }
313321 }
314322
315323 return {
@@ -616,7 +624,14 @@ async function publishWorkspaceApiTagLink(
616624 }
617625 const payload = buildLinkPayload ( context , meta . workspaceLinkIdProperty , 'apis' , apiName , descriptor . workspace ) ;
618626
619- await client . putResource ( context , descriptor , payload ) ;
627+ try {
628+ await client . putResource ( context , descriptor , payload ) ;
629+ } catch ( error ) {
630+ // 409 means the tag/api link already exists — desired state is in place.
631+ if ( ! isLinkAlreadyExistsError ( error ) ) {
632+ throw error ;
633+ }
634+ }
620635
621636 return {
622637 descriptor,
0 commit comments