[SOLVED] Bug - during update (.NET client - POST)

I have…

I’m submitting a…

  • [ ] Regression (a behavior that stopped working in a new release)
  • [x] Bug report
  • [ ] Performance issue
  • [ ] Documentation issue or request

Current behavior

When I call ‘UpdateAsync’ with dotnet SquidexClient I got error 409 (Entity ..id.. already exists. ).

Expected behavior

Update entry and return OK 200

Minimal reproduction of the problem

  1. Step app with on version 4.7.3 (with existing data for some time)
  2. Clean installation with 4.7.3
  3. Restore in clean installation (using build-in backup from original server)
  4. Update with docker to 5.3.0
  5. In C# use SquidexClient to perform update (load data, change something, call UpdateAsync)

info: It is not minimal reproduction of the problem. Not sure if this happens without the migration step. I assume that basic scenario with just update on a new/clean project is covered by tests (from what i see in GitHub repo it is).

Environment

  • [x] Self hosted with docker
  • [ ] Self hosted with IIS
  • [ ] Self hosted with other version
  • [ ] Cloud version

Version: 5.3.0

Others:

I recently migrate our solution from Squidex 4.7.3 to squidex 5.3.0. I migrated late because of, some issue during migration. I solve this with a clean installation and cloning just ‘app’ what I care about and then migration work (build-in restore).

NOTE: Maybe related to build-in restore function.

Then for developing I use build-in restoring again to clone this app to my local machine. But there is the issue. When I call ‘UpdateAsync’ with dotnet SquidexClient I got error 409 (Entity ..id.. already exists. ). It must actually exist if I call update (at the same instance what I got from SquidexClient).

I also discover, that if I make exact same call from Postman but instead of POST use PUT. It works and also then I actually can call POST and it works also. Base on this behavior I believe it must be some bug in Squidex which assumes somewhere it is not updated call but insert.

DEBUG information:

Response from API to call made by squidex client (dotnet)

Squidex Request failed: {"message":"Entity (f130f052-1f63-4f74-9c57-e10900dda306--c31aea85-b53c-470c-8877-5968cba486c0) already exists.","traceId":"|2d444230-4b47e7f51982f00b.","type":"https://tools.ietf.org/html/rfc7231#section-6.5.8","statusCode":409}

Request sent by dotnet client

POST /api/content/test-1/cities/c31aea85-b53c-470c-8877-5968cba486c0 HTTP/1.1
Host: squidex.local:10443
Authorization: Bearer ..token..
Accept-Encoding: gzip, deflate
Content-Type: application/json; charset=utf-8
Content-Length: 1001

{
  ...json...
}

Exact same request work if I copy the content to postman and send it as PUT

PUT /api/content/test-1/cities/c31aea85-b53c-470c-8877-5968cba486c0 HTTP/1.1
...

Then I can again send the exact same request with postmen as POST and it works again.

Log
(one day older, I actually try to make a clean local installation and restore the application from backup again).

2020-11-14T21:05:34.811013900Z 
{
  "logLevel": "Error",
  "action": "GrainInvoked",
  "status": "Failed",
  "grain": "Squidex.Domain.Apps.Entities.Contents.ContentDomainObjectGrain",
  "grainMethod": "System.Threading.Tasks.Task\u00601[Squidex.Infrastructure.Orleans.J\u00601[System.Object]] Squidex.Infrastructure.Commands.IDomainObjectGrain.ExecuteAsync(Squidex.Infrastructure.Orleans.J\u00601[Squidex.Infrastructure.Commands.CommandRequest])",
  "app": {
    "name": "Squidex",
    "version": "5.3.0.0",
    "sessionId": "76ccd2c8-fab1-44b9-abb8-20c68bc9e85e"
  },
  "web": {
    "requestId": "|f2fe6cd8-4af645b40e24f211.",
    "requestPath": "/content/test-2/cities/d76ea5a7-1a45-4421-a2bc-b33f53d3ddb3",
    "requestMethod": "POST",
    "routeValues": {
      "area": "Api",
      "action": "PostContent",
      "controller": "Contents"
    }
  },
  "timestamp": "2020-11-14T21:05:37Z",
  "exception": {
    "type": "Squidex.Infrastructure.DomainObjectConflictException",
    "message": "Entity (b8ea3193-a8d6-455b-a638-0e8493dc02a7--d76ea5a7-1a45-4421-a2bc-b33f53d3ddb3) already exists.",
    "stackTrace": "   at Squidex.Infrastructure.Commands.DomainObjectBase\u00601.InvokeAsync[TCommand](TCommand command, Func\u00602 handler, Boolean isUpdate) in /src/src/Squidex.Infrastructure/Commands/DomainObjectBase.cs:line 231\n   at Squidex.Infrastructure.Commands.DomainObjectGrain\u00602.ExecuteAsync(J\u00601 request) in /src/src/Squidex.Infrastructure/Commands/DomainObjectGrain.cs:line 50\n   at Squidex.Domain.Apps.Entities.Contents.OrleansCodeGenContentGrainMethodInvoker.Invoke(IAddressable grain, InvokeMethodRequest request) in /src/src/Squidex.Domain.Apps.Entities/obj/Release/netcoreapp3.1/Squidex.Domain.Apps.Entities.orleans.g.cs:line 1425\n   at Orleans.Runtime.GrainMethodInvoker.Invoke()\n   at Squidex.Infrastructure.Orleans.StateFilter.Invoke(IIncomingGrainCallContext context) in /src/src/Squidex.Infrastructure/Orleans/StateFilter.cs:line 51\n   at Orleans.Runtime.GrainMethodInvoker.Invoke()\n   at Squidex.Infrastructure.Orleans.LocalCacheFilter.Invoke(IIncomingGrainCallContext context) in /src/src/Squidex.Infrastructure/Orleans/LocalCacheFilter.cs:line 39\n   at Orleans.Runtime.GrainMethodInvoker.Invoke()\n   at Orleans.Runtime.GrainMethodInvoker.Invoke()\n   at Squidex.Infrastructure.Orleans.ExceptionWrapperFilter.Invoke(IIncomingGrainCallContext context) in /src/src/Squidex.Infrastructure/Orleans/ExceptionWrapperFilter.cs:line 35\n   at Orleans.Runtime.GrainMethodInvoker.Invoke()\n   at Squidex.Infrastructure.Orleans.LoggingFilter.Invoke(IIncomingGrainCallContext context) in /src/src/Squidex.Infrastructure/Orleans/LoggingFilter.cs:line 46"
  }
}
2020-11-14T21:05:37.985297800Z 
{
  "logLevel": "Information",
  "filters": {
    "appId": "b8ea3193-a8d6-455b-a638-0e8493dc02a7",
    "appName": "test-2",
    "clientId": "test-2:default",
    "costs": 1
  },
  "elapsedRequestMs": 29,
  "app": {
    "name": "Squidex",
    "version": "5.3.0.0",
    "sessionId": "76ccd2c8-fab1-44b9-abb8-20c68bc9e85e"
  },
  "web": {
    "requestId": "|f2fe6cd8-4af645b40e24f211.",
    "requestPath": "/api/content/test-2/cities/d76ea5a7-1a45-4421-a2bc-b33f53d3ddb3",
    "requestMethod": "POST"
  },
  "timestamp": "2020-11-14T21:05:37Z"
}

I think one problem is the client library. I don’t know why I have changed it to use the new upsert endpoint for updates. It is a bad idea, because it has 2 issues:

  1. Not compatible with older versions.
  2. Can unintentionally create new content items.

EDIT: But I cannot reproduce it, why the upsert fails…

I have pushed a new version of the client library to nuget. Should be there any minute.

1 Like

Btw: What issue do you have with migration? Could you provide me a reproducible version? e.g. small c# repository and a backup of your mongo DB?

I try to restore the app once again in my local env. And now it works as expected = original issue could be marked as SOLVED.

EDIT: And thanks for fast resolving during sunday!

I send you more info via PM. I isnt related to C# it is purly issue with migration which do not finished and squidex do not start at all.

1 Like