Search code examples
sqlbuildbuild-definition

TFS2018 Build definition save error - Counter with name %counterName="BuildFolderId";% does not exist


i have a problem with a newly migrated TFS On-permise from 2015update1 to 2018update2

I create a new build definition, and when i click on "save", i have the following message:

%error="800095";%:TFSSERVER.Tfs_DefaultCollection.dbo.prc_iCounterGetNext: Counter with name %counterName="BuildFolderId";% does not exist

%error="901004";%:TFSSERVER.Tfs_DefaultCollection.prc_iiEnsureFolder: Database Update Failure - Error %error="800095";% executing EXEC statement for prc_iCounterGetNext

%error="901004";%:TFSSERVER.Tfs_DefaultCollection.prc_AddDefinition: Database Update Failure - Error %error="901004";% executing EXEC statement for Build.prc_iiEnsureFolder

It's strangly similar to developer community witch have been resovle by executing a query on sql database given in the TFS2017Update1 release note - known issues:

INSERT  tbl_Counter (PartitionId, DataspaceId, CounterName, CounterValue)
SELECT  DISTINCT
      dpm.PartitionId,
      ds.DataspaceId,
      N'TaskReferenceId',
      1
FROM    tbl_DatabasePartitionMap dpm
INNER LOOP JOIN Task.tbl_Hub h
ON      h.PartitionId = dpm.PartitionId
INNER LOOP JOIN tbl_Dataspace ds
ON      ds.PartitionId = dpm.PartitionId
      AND ds.DataspaceCategory = h.DataspaceCategory
      AND ds.DataspaceIdentifier <> '00000000-0000-0000-0000-000000000000'
WHERE   dpm.PartitionId > 0
      AND dpm.HostType = 4
      AND NOT EXISTS (
          SELECT  *
          FROM    tbl_Counter c
          WHERE   c.PartitionId = dpm.PartitionId
                  AND c.DataspaceId = ds.DataspaceId
                  AND c.CounterName = N'TaskReferenceId'
      )

Thanks for your help.


Solution

  • i finally found my way through this problem

    1. How to know the correct DataspaceId:

      SELECT TOP 1000 [PartitionId] ,[ProjectId],[DataspaceId], [ProjectUri],ProjectName],[SequenceId],[IsDeleted], [IsResolutionStateCustomized],[IsFailureTypeCustomized],[MigrationState], [MigrationError] FROM [Tfs_DefaultCollection].[dbo].[tbl_Project] WHERE ProjectName = "My project witch having an error"

    The end of string in the column [ProjectUri] contains the unique id of the project (in my case vstfs:///Classification/TeamProject/b96fbc5b-7bf3-452b-894f-6f5b4bb801c0)

    1. How to know the corresponding DataspaceId

      SELECT TOP 1000 [PartitionId] ,[DataspaceCategory] ,[DataspaceIdentifier] ,[DataspaceId] ,[DatabaseId] ,[State] FROM [Tfs_DefaultCollection].[dbo].[tbl_Dataspace] where DataspaceIdentifier="b96fbc5b-7bf3-452b-894f-6f5b4bb801c0" and DataspaceCategory="Build"

    It gave me my Dataspace ID : 726

    1. Check if there is no record in the table [Build].[tbl_Folder]

      SELECT TOP 1000 [PartitionId] ,[DataspaceId] ,[FolderId] ,[FolderPath] ,[FolderName] ,[CreatedBy] ,[CreatedOn] ,[Description] ,[ChangedBy] ,[ChangedOn] ,[Deleted] FROM [Tfs_DefaultCollection].[Build].[tbl_Folder] WHERE DataspaceId=726

    If there is no record, i have to create one.

    INSERT INTO [Build].[tbl_Folder]
           ([PartitionId]
           ,[DataspaceId]
           ,[FolderId]
           ,[FolderPath]
           ,[FolderName]
           ,[CreatedBy]
           ,[CreatedOn]
           ,[Description]
           ,[ChangedBy]
           ,[ChangedOn]
           ,[Deleted])
     VALUES
           (1
           ,726
           ,1
           ,''
           ,'\'
           ,'00000000-0000-0000-0000-000000000000'
           ,CURRENT_TIMESTAMP
           ,NULL
           ,NULL
           ,NULL
           ,0)
    GO
    
    1. Check if there is no record in the table [tbl_Counter] with this DataspaceId

      SELECT TOP 1000 [PartitionId],[DataspaceId],[CounterName],[CounterValue] FROM [Tfs_DefaultCollection].[dbo].[tbl_Counter] where CounterName='BuildFolderId' and DataspaceId=726

    If there is no record, i have to create one.

    INSERT INTO [dbo].[tbl_Counter]
           ([PartitionId]
           ,[DataspaceId]
           ,[CounterName]
           ,[CounterValue])
     VALUES
           (1
           ,726
           ,'BuildFolderId'
           ,2)
     GO
    

    After that, i am able to save my build definition.

    Other error appears when i try to launch my build definition:

    %error="800095";%:TFSSERVER.Tfs_DefaultCollection.dbo.prc_iCounterGetNext: Counter with name %counterName="TimelineStringId";% does not exist
    

    based on the previous script i insert new value in the table [tbl_Counter]

    INSERT INTO [dbo].[tbl_Counter]
           ([PartitionId]
           ,[DataspaceId]
           ,[CounterName]
           ,[CounterValue])
     VALUES
           (1
           ,726
           ,'TimelineStringId'
           ,2)
     GO
    

    Finally i have one remaing error:

    %error="800095";%:TFSSERVER.Tfs_DefaultCollection.dbo.prc_iCounterGetNext: Counter with name %counterName="TaskOrchestrationPlanId";% does not exist
    

    so:

    INSERT INTO [dbo].[tbl_Counter]
           ([PartitionId]
           ,[DataspaceId]
           ,[CounterName]
           ,[CounterValue])
     VALUES
           (1
           ,726
           ,'TaskOrchestrationPlanId'
           ,2)
     GO
    

    I'm finally able to launch successfully my build definition.

    Hope that could help someone.

    i write a sql script in two version, one for TFS2018 and one other for TFS2015

    change the variable @projectName by your real project name.
    The TFS2018 version:

    USE [Tfs_DefaultCollection]
    GO
    declare @projectUriGlobal varchar(max);
    declare @projectName varchar(max);
    declare @DataspaceIdentifier varchar(max);
    declare @DataspaceId int;
    select @projectName='MyProjectName'
    select @projectUriGlobal = (select [ProjectUri] from [tbl_Project] where ProjectName=@projectName)
    select @DataspaceIdentifier = (select right(@projectUriGlobal, charindex('/', reverse(@projectUriGlobal) + '/') - 1))
    if not exists(select DataspaceId from [tbl_Dataspace] where DataspaceIdentifier = @DataspaceIdentifier and DataspaceCategory='Build')
    BEGIN
      PRINT 'Création d" un enregistrement dans [tbl_Dataspace] pour le DataspaceIdentifier '+@DataspaceIdentifier;
      INSERT INTO [tbl_Dataspace] VALUES (1,'Build', @DataspaceIdentifier,1,1)
    END
    
    select  @DataspaceId = (select DataspaceId from [tbl_Dataspace] where DataspaceIdentifier = @DataspaceIdentifier and DataspaceCategory='Build')
    
    PRINT 'Project Name : '+@projectName;
    PRINT 'Project Uri :'+  @projectUriGlobal
    PRINT 'DataspaceIdentifier : '+ @DataspaceIdentifier
    PRINT 'DataSpaceID : '+ CAST(@DataspaceId as varchar)
    
    if EXISTS(SELECT TOP 1 [DataspaceId] FROM [Build].[tbl_Folder] where DataspaceId=@DataspaceId)
    BEGIN
      PRINT 'Pas d"enregistrement a creer dans [Build].[tbl_Folder] pour le dataspace ID '+ CAST(@DataspaceId as varchar) +' car existe déjà'
    END
    ELSE
    BEGIN
      PRINT 'Creation d"un enregistrement dans la table [Build].[tbl_Folder] pour le dataspace ID '+ CAST(@DataspaceId as varchar)
      INSERT INTO [Build].[tbl_Folder] ([PartitionId] ,[DataspaceId],[FolderId],[FolderPath],[FolderName],[CreatedBy],[CreatedOn],[Description],[ChangedBy],[ChangedOn],[Deleted])
            VALUES (1,@DataspaceId,1,'','\','00000000-0000-0000-0000-000000000000',CURRENT_TIMESTAMP,NULL ,NULL,NULL,0)
    END
    
    if EXISTS(SELECT TOP 1 [PartitionId],[DataspaceId],[CounterName] FROM [tbl_Counter]  where CounterName='BuildFolderId' and DataspaceId=@DataspaceId)
    BEGIN
       PRINT 'Pas d"enregistrement a creer dans la table [tbl_Counter] pour le dataspace ID '+ CAST(@DataspaceId as varchar) +' avec le counterName=BuildFolderId  car existe déjà';
    END
    ELSE
    BEGIN
       PRINT 'Creation d"un enregistrement dans la table [tbl_Counter] pour le dataspace ID '+ CAST(@DataspaceId as varchar) +' avec le counterName=BuildFolderId';
       INSERT INTO [dbo].[tbl_Counter] ([PartitionId],[DataspaceId],[CounterName],[CounterValue]) VALUES (1,@DataspaceId,'BuildFolderId',2)
    END
    
    if EXISTS(SELECT TOP 1 [PartitionId],[DataspaceId],[CounterName] FROM [tbl_Counter]  where CounterName='TimelineStringId' and DataspaceId=@DataspaceId)
    BEGIN
       PRINT 'Pas d"enregistrement a creer dans la table [tbl_Counter] pour le dataspace ID '+ CAST(@DataspaceId as varchar) +' avec le counterName=TimelineStringId  car existe déjà';
    END
    ELSE
    BEGIN
       PRINT 'Creation d"un enregistrement dans la table [tbl_Counter] pour le dataspace ID '+ CAST(@DataspaceId as varchar) +' avec le counterName=TimelineStringId';
       INSERT INTO [dbo].[tbl_Counter] ([PartitionId],[DataspaceId],[CounterName],[CounterValue]) VALUES (1,@DataspaceId,'TimelineStringId',2)
    END
    
    if EXISTS(SELECT TOP 1 [PartitionId],[DataspaceId],[CounterName] FROM [tbl_Counter]  where CounterName='TaskOrchestrationPlanId' and DataspaceId=@DataspaceId)
    BEGIN
       PRINT 'Pas d"enregistrement a creer dans la table [tbl_Counter] pour le dataspace ID '+ CAST(@DataspaceId as varchar) +' avec le counterName=TaskOrchestrationPlanId  car existe déjà';
    END
    ELSE
    BEGIN
       PRINT 'Creation d"un enregistrement dans la table [tbl_Counter] pour le dataspace ID '+ CAST(@DataspaceId as varchar) +' avec le counterName=TaskOrchestrationPlanId';
       INSERT INTO [dbo].[tbl_Counter] ([PartitionId],[DataspaceId],[CounterName],[CounterValue]) VALUES (1,@DataspaceId,'TaskOrchestrationPlanId',2)
    END
    

    And the version for TFS2015 would be

    USE [Tfs_DefaultCollection]
    GO
    declare @projectUriGlobal varchar(max);
    declare @projectName varchar(max);
    declare @DataspaceIdentifier varchar(max);
    declare @DataspaceId int;
    
    select @projectName='MyProjectName'
    select @projectUriGlobal = (select [ProjectUri] from [tbl_Project] where ProjectName=@projectName)
    select @DataspaceIdentifier = (select right(@projectUriGlobal, charindex('/', reverse(@projectUriGlobal) + '/') - 1))
    if not exists(select DataspaceId from [tbl_Dataspace] where DataspaceIdentifier = @DataspaceIdentifier and DataspaceCategory='Build')
    BEGIN
      PRINT 'Création d" un enregistrement dans [tbl_Dataspace] pour le DataspaceIdentifier '+@DataspaceIdentifier;
      INSERT INTO [tbl_Dataspace] VALUES (1,'Build', @DataspaceIdentifier,1,1)
    END
    
    select  @DataspaceId = (select DataspaceId from [tbl_Dataspace] where DataspaceIdentifier = @DataspaceIdentifier and DataspaceCategory='Build')
    
    PRINT 'Project Name : '+@projectName;
    PRINT 'Project Uri :'+  @projectUriGlobal
    PRINT 'DataspaceIdentifier : '+ @DataspaceIdentifier
    PRINT 'DataSpaceID : '+ CAST(@DataspaceId as varchar)
    
    if EXISTS(SELECT TOP 1 [PartitionId],[DataspaceId],[CounterName] FROM [tbl_Counter]  where CounterName='BuildFolderId' and DataspaceId=@DataspaceId)
    BEGIN
       PRINT 'Pas d"enregistrement a creer dans la table [tbl_Counter] pour le dataspace ID '+ CAST(@DataspaceId as varchar) +' avec le counterName=BuildFolderId  car existe déjà';
    END
    ELSE
    BEGIN
       PRINT 'Creation d"un enregistrement dans la table [tbl_Counter] pour le dataspace ID '+ CAST(@DataspaceId as varchar) +' avec le counterName=BuildFolderId';
       INSERT INTO [dbo].[tbl_Counter] ([PartitionId],[DataspaceId],[CounterName],[CounterValue]) VALUES (1,@DataspaceId,'BuildFolderId',2)
    END
    
    if EXISTS(SELECT TOP 1 [PartitionId],[DataspaceId],[CounterName] FROM [tbl_Counter]  where CounterName='TimelineStringId' and DataspaceId=@DataspaceId)
    BEGIN
       PRINT 'Pas d"enregistrement a creer dans la table [tbl_Counter] pour le dataspace ID '+ CAST(@DataspaceId as varchar) +' avec le counterName=TimelineStringId  car existe déjà';
    END
    ELSE
    BEGIN
       PRINT 'Creation d"un enregistrement dans la table [tbl_Counter] pour le dataspace ID '+ CAST(@DataspaceId as varchar) +' avec le counterName=TimelineStringId';
       INSERT INTO [dbo].[tbl_Counter] ([PartitionId],[DataspaceId],[CounterName],[CounterValue]) VALUES (1,@DataspaceId,'TimelineStringId',2)
    END
    
    if EXISTS(SELECT TOP 1 [PartitionId],[DataspaceId],[CounterName] FROM [tbl_Counter]  where CounterName='TaskOrchestrationPlanId' and DataspaceId=@DataspaceId)
    BEGIN
       PRINT 'Pas d"enregistrement a creer dans la table [tbl_Counter] pour le dataspace ID '+ CAST(@DataspaceId as varchar) +' avec le counterName=TaskOrchestrationPlanId  car existe déjà';
    END
    ELSE
    BEGIN
       PRINT 'Creation d"un enregistrement dans la table [tbl_Counter] pour le dataspace ID '+ CAST(@DataspaceId as varchar) +' avec le counterName=TaskOrchestrationPlanId';
       INSERT INTO [dbo].[tbl_Counter] ([PartitionId],[DataspaceId],[CounterName],[CounterValue]) VALUES (1,@DataspaceId,'TaskOrchestrationPlanId',2)
    END