[NOT_REPRODUCIBLE] SquidexClient library fails to delete Squidex Content items with non-guid Identity/SquidexId

I’m trying to delete and bulk delete squidex content items with a non-guid Identity/SquidexId using Squidex Client library version 10.2.0 (was a given try on the latest version 10.7.0 also).

I’m submitting a…

  • [ ] Bug report

Current behavior

When calling squidexClient.BulkUpdateAsync(bulkUpdate) with BulkUpdateJobs of type

new BulkUpdateJob()
{
Id = squidexId,
Schema = schemaName,
Type = BulkUpdateType.Delete,
Permanent = true
}

Where squidexId is a string in format

“author-12345”, “author-12345–some-fragment-text”
template: {ContentType}-{id} [–{content.FragmentText}].

After BulkUpdateAsync() executed - BulkResult items have status 500 error, without any error message.

Same happens for

squidexClient.DeleteAsync(squidexId, new ContentDeleteOptions { Permanent = isPermanent }).

Expected behavior

Content items with non-guid SquidexId successfully deleted, as same as items that have Guid as SquidexId.

Minimal reproduction of the problem

  1. Create content items in Squidex using BulkMode with setting a SquidexId/Identity as non-guid value, in format {ContentType}-{id} [–{content.FragmentText}], example “author-12345–some-fragment-text”.
    Example:

new BulkUpdateJob
{
Data = contentLink,
Schema = SchemaNames.ContentLinks,
Type = BulkUpdateType.Create,
Status = “Draft”
Id = $"{idPrefix}-{contentLink.DomainId}–{contentLink.FragmentId}"
}

  1. Try to delete them using SquidexClient Library in bulk and non-bulk mode, targeting with squidexId
  2. See error status 500 returns in BulkResult, and Squidex logs has some additional info (attached in the end)

Environment

  • [ ] Cloud version

Version: 7.3.0

Browser:

  • Browser is not used

Others:

Squidex Logs for an error case.

errormessage
Failed to execute content bulk job with index 3727 of type Delete.

exception.message
Requested version -1, but found 0.

exception.type
Squidex.Infrastructure.States.InconsistentStateException

exception.stackTrace
at Squidex.Infrastructure.States.Persistence1.WriteEventsAsync(IReadOnlyList1 events, CancellationToken ct) in C:\src\src\Squidex.Infrastructure\States\Persistence.cs:line 234
at Squidex.Infrastructure.Commands.DomainObject1.DeleteCoreAsync[TCommand](TCommand command, Func3 handler, CancellationToken ct) in C:\src\src\Squidex.Infrastructure\Commands\DomainObject.cs:line 207
at Squidex.Infrastructure.Commands.DomainObject1.DeletePermanentAsync[TCommand](TCommand command, Func3 handler, CancellationToken ct) in C:\src\src\Squidex.Infrastructure\Commands\DomainObject.Execute.cs:line 156
at Squidex.Infrastructure.Commands.CachingDomainObjectMiddleware3.ExecuteCommandAsync(T executable, TCommand command, CancellationToken ct) in C:\src\src\Squidex.Infrastructure\Commands\CachingDomainObjectMiddleware.cs:line 38 at Squidex.Infrastructure.Commands.AggregateCommandMiddleware2.ExecuteCommandAsync(CommandContext context, CancellationToken ct) in C:\src\src\Squidex.Infrastructure\Commands\AggregateCommandMiddleware.cs:line 38
at Squidex.Infrastructure.Commands.AggregateCommandMiddleware2.HandleAsync(CommandContext context, NextDelegate next, CancellationToken ct) in C:\src\src\Squidex.Infrastructure\Commands\AggregateCommandMiddleware.cs:line 26 at Squidex.Domain.Apps.Entities.Contents.DomainObject.ContentsBulkUpdateCommandMiddleware.HandleAsync(CommandContext context, NextDelegate next, CancellationToken ct) in C:\src\src\Squidex.Domain.Apps.Entities\Contents\DomainObject\ContentsBulkUpdateCommandMiddleware.cs:line 136 at Squidex.Infrastructure.Commands.AggregateCommandMiddleware2.HandleAsync(CommandContext context, NextDelegate next, CancellationToken ct) in C:\src\src\Squidex.Infrastructure\Commands\AggregateCommandMiddleware.cs:line 26
at Squidex.Domain.Apps.Entities.Comments.DomainObject.CommentsCommandMiddleware.HandleAsync(CommandContext context, NextDelegate next, CancellationToken ct) in C:\src\src\Squidex.Domain.Apps.Entities\Comments\DomainObject\CommentsCommandMiddleware.cs:line 38
at Squidex.Infrastructure.Commands.AggregateCommandMiddleware2.HandleAsync(CommandContext context, NextDelegate next, CancellationToken ct) in C:\src\src\Squidex.Infrastructure\Commands\AggregateCommandMiddleware.cs:line 26 at Squidex.Domain.Apps.Entities.Assets.DomainObject.AssetCommandMiddleware.HandleAsync(CommandContext context, NextDelegate next, CancellationToken ct) in C:\src\src\Squidex.Domain.Apps.Entities\Assets\DomainObject\AssetCommandMiddleware.cs:line 66 at Squidex.Domain.Apps.Entities.Assets.DomainObject.AssetsBulkUpdateCommandMiddleware.HandleAsync(CommandContext context, NextDelegate next, CancellationToken ct) in C:\src\src\Squidex.Domain.Apps.Entities\Assets\DomainObject\AssetsBulkUpdateCommandMiddleware.cs:line 130 at Squidex.Infrastructure.Commands.AggregateCommandMiddleware2.HandleAsync(CommandContext context, NextDelegate next, CancellationToken ct) in C:\src\src\Squidex.Infrastructure\Commands\AggregateCommandMiddleware.cs:line 26
at Squidex.Domain.Apps.Entities.Apps.DomainObject.AppCommandMiddleware.HandleAsync(CommandContext context, NextDelegate next, CancellationToken ct) in C:\src\src\Squidex.Domain.Apps.Entities\Apps\DomainObject\AppCommandMiddleware.cs:line 40
at Squidex.Domain.Apps.Entities.Schemas.Indexes.SchemasIndex.HandleAsync(CommandContext context, NextDelegate next, CancellationToken ct) in C:\src\src\Squidex.Domain.Apps.Entities\Schemas\Indexes\SchemasIndex.cs:line 152
at Squidex.Domain.Apps.Entities.Apps.Indexes.AppsIndex.HandleAsync(CommandContext context, NextDelegate next, CancellationToken ct) in C:\src\src\Squidex.Domain.Apps.Entities\Apps\Indexes\AppsIndex.cs:line 189
at Squidex.Domain.Apps.Entities.Invitation.InviteUserCommandMiddleware.HandleAsync(CommandContext context, NextDelegate next, CancellationToken ct) in C:\src\src\Squidex.Domain.Apps.Entities\Invitation\InviteUserCommandMiddleware.cs:line 68
at Squidex.Domain.Apps.Entities.Apps.Plans.RestrictAppsCommandMiddleware.HandleAsync(CommandContext context, NextDelegate next, CancellationToken ct) in C:\src\src\Squidex.Domain.Apps.Entities\Apps\Plans\RestrictAppsCommandMiddleware.cs:line 63
at Squidex.Domain.Apps.Entities.Apps.AlwaysCreateClientCommandMiddleware.HandleAsync(CommandContext context, NextDelegate next, CancellationToken ct) in C:\src\src\Squidex.Domain.Apps.Entities\Apps\AlwaysCreateClientCommandMiddleware.cs:line 38
at Squidex.Domain.Apps.Entities.Apps.Templates.TemplateCommandMiddleware.HandleAsync(CommandContext context, NextDelegate next, CancellationToken ct) in C:\src\src\Squidex.Domain.Apps.Entities\Apps\Templates\TemplateCommandMiddleware.cs:line 55
at Squidex.Infrastructure.Commands.CustomCommandMiddlewareRunner.HandleAsync(CommandContext context, NextDelegate next, CancellationToken ct) in C:\src\src\Squidex.Infrastructure\Commands\CustomCommandMiddlewareRunner.cs:line 27
at Squidex.Web.CommandMiddlewares.ETagCommandMiddleware.HandleAsync(CommandContext context, NextDelegate next, CancellationToken ct) in C:\src\src\Squidex.Web\CommandMiddlewares\ETagCommandMiddleware.cs:line 61
at Squidex.Infrastructure.Commands.InMemoryCommandBus.PublishAsync(ICommand command, CancellationToken ct) in C:\src\src\Squidex.Infrastructure\Commands\InMemoryCommandBus.cs:line 43
at Squidex.Domain.Apps.Entities.Contents.DomainObject.ContentsBulkUpdateCommandMiddleware.ExecuteCommandAsync(BulkTaskCommand bulkCommand) in C:\src\src\Squidex.Domain.Apps.Entities\Contents\DomainObject\ContentsBulkUpdateCommandMiddleware.cs:line 158

One more addditional detail - the only way found to delete this content items by http request - is Squidex API content delete endpoint.
<base_url>/api/content/corecms/content-links/{id}

Please use code blocks. It is super hard to read…

Ok, sorry. Did some adjustments to current report. Hope it helps :slight_smile:

I have added a test to the test suite and I do not have a problem:

[Fact]
    public async Task Should_create_content_with_custom_id_and_delete_it()
    {
        var id = "author-12345–fragment-text";

        // STEP 1: Create a new item with a custom id.
        var options = new ContentCreateOptions { Id = id, Publish = true };

        var content = await _.Contents.CreateAsync(new TestEntityData
        {
            Number = 1
        }, options);

        Assert.Equal(id, content.Id);


        // STEP 2: Delete with bulk update.
        await _.Contents.BulkUpdateAsync(new BulkUpdate
        {
            Jobs = new List<BulkUpdateJob>
            {
                new BulkUpdateJob
                {
                    Type = BulkUpdateType.Delete,
                    Id = id
                }
            }
        });


        // STEP 3: Retrieve all items and ensure that the deleted item does not exist.
        var updated = await _.Contents.GetAsync();

        Assert.DoesNotContain(updated.Items, x => x.Id == id);
    }

Are you sure that you are not updating or deleting the same content twice in the same bulk update? Could just be a problem with parallelization.

No, no any content is deleted twice in the same bulkUpdate. And doesn’t matter bulk or non-bulk.

Don’t know what’s going on environment, but content with this custom ID is not being deleted in any way.
The only thing that helps - to delete the squidex App, wait some time, and re-create it.
And less helps to mark that items with flag-deleted, without Permanent = true parameter, because the request fails with status 500.

I think I’ll ask my devlead to continue with the investigation around this. He’ll come back when ready.

1 Like

Hi @Sebastian, just to clarify based on your test does the app ID get automatically prefixed within the Squidex.ClientLibrary so we should only provide the custom part of the ID when using bulk deletion?

Relates to:

No, the prefix is done internally and nothing you have to handle.