I'm trying to create block_content entities, but I'm getting 422 unprocessable entity.
Clean installation using the standard profile and enabling just jsonapi.

POST /jsonapi/block_content/basic

{
    "data": {
        "type": "block_content--basic",
        "attributes": {
            "langcode": "en",
            "status": true,
            "info": "Testing block_content",
            "reusable": true,
            "default_langcode": true,
            "body": {
                "value": "<p>Body</p>\r\n",
                "format": "basic_html"
            }
        }
    }
}

Also I tried just adding the info attribute without the others, same result.

Comments

schlaukopf created an issue. See original summary.

gabesullice’s picture

Title: 422 unprocessable entity when try to create a block content » 422 unprocessable entity when trying to create a block content
Category: Bug report » Support request
Status: Active » Postponed (maintainer needs more info)
Issue tags: +API-First Initiative

I attempted to replicate this. I gave the anonymous user the administer blocks permission so that I would have permission to POST a new block without any authentication.

I got the following response:

{
    "errors": [
        {
            "title": "Unprocessable Entity",
            "status": 422,
            "detail": "body.0.format: The value you selected is not a valid choice.",
            "source": {
                "pointer": "/data/attributes/body/format"
            }
        }
    ],
    "jsonapi": {
        "version": "1.0",
        "meta": {
            "links": {
                "self": {
                    "href": "http://jsonapi.org/format/1.0/"
                }
            }
        }
    }
}

Once I gave the anonymous role the "Use the Basic HTML text format" permission, I was able to successfully create the new block.

Does your user have that permission?

wim leers’s picture

Title: 422 unprocessable entity when trying to create a block content » [upstream] 422 unprocessable entity when trying to create a block content
Issue tags: +Needs upstream bugfix

It's interesting that it's a 422 instead of a 403 though. That's interesting.

Did some digging.

Turns out this is a consequence of \Drupal\filter\Plugin\DataType\FilterFormat doing this:

  public function getSettableOptions(AccountInterface $account = NULL) {
    // @todo: Avoid calling functions but move to injected dependencies.
    return array_map(function ($format) {
      return $format->label();
    }, filter_formats($account));
  }

IOW: the options available are limited to those for the current account. But that is a semantically different thing: disallowed_format_name is a settable option, it's just not settable by the current user. If you'd pass nonsense as the format, it should be a 422, if you pass disallowed_format_name, it should result in a 403.

schlaukopf’s picture

Thank you for you fast response, I'm using the cookie session from the admin (uid=1), so it should have all permissions, anyway I tried adding those permissions to the anonymous user, but I'm still getting the same error, and as I mentioned before the error appears even without body. Also I'm able to create article with basic_html format, and no issues, the problem is just with block:content entities.
You can take a look here testingjsonapier9bvqszma.devcloud.acquia-sites.com.

wim leers’s picture

Oh, interesting! If that’s what’s happening, it would be very easy to add a failing test to JsonApiRegressionTest. There are lots of examples in there already. Could you add a test for this use case? 🙏

schlaukopf’s picture

@Wim leers I found what is the issue, it was failing because there was already a block with the same name, lol, I tried different things, but I never thought that it could be the name. so is this expected? or Is a code when the entity already exists?

schlaukopf’s picture

Now I tried using the basic auth module instead of the cookie session, and now I can see the error response(json), when I used the session cookie I just got error but no response. that's why it wasn't clear for me exactly where was the error

schlaukopf’s picture

Also I found using the http basic auth and trying to create the block with the same name.
-When I use the user 1, I got 403 with the error response (json) "The 'administer blocks' permission is required.".
-When I create a new user and assign the rol administrator, I got 422 but without body (content length 0)
-When I create a new user with a new rol and with the administer blocks permission, I got 422 with the error response (json) info: A custom block with block description xxx already exists."
shouldn't get the two first scenarios the same response as the third one?

wim leers’s picture

#6:

@Wim leers I found what is the issue, it was failing because there was already a block with the same name, lol, I tried different things, but I never thought that it could be the name. so is this expected? or Is a code when the entity already exists?

If that's really what's going on here, then that would be an important bug to fix, because if that's truly what's happening, you're getting the wrong validation error. Because \Drupal\block_content\Entity\BlockContent::baseFieldDefinitions() contains this:

    $fields['info'] = BaseFieldDefinition::create('string')
…
      ->addConstraint('UniqueField', []);

Which means you should get \Drupal\Core\Validation\Plugin\Validation\Constraint\UniqueFieldConstraint's error message, which is very different.

But in #8 you are getting that error response. So are you sure you're reporting things accurately here?


#8: That too sounds very strange. And indeed in all three scenarios you should get the same error message as that third scenario. Could you please add that scenario to JsonApiRegressionTest?

schlaukopf’s picture

StatusFileSize
new119.05 KB

I will try to add them to the regression test.
So for recap, in all scenarios I should get this error,

{
    "errors": [
        {
            "title": "Unprocessable Entity",
            "status": 422,
            "detail": "info: A custom block with block description Testing block already exists.",
            "source": {
                "pointer": "/data/attributes/info"
            }
        }
    ],
    "jsonapi": {
        "version": "1.0",
        "meta": {
            "links": {
                "self": {
                    "href": "http://jsonapi.org/format/1.0/"
                }
            }
        }
    }
}

But depending of which user and auth method, I'm getting different results as shown below.
scenarios
From these 6 scenarios, I'm a little worried about the first one, I don't understand, why I need to add that permission to the anonymous user as described in #2, if I'm logged as user 1. Or am I missing something?

wim leers’s picture

It doesn't make sense to me either that the first scenario would behave differently. The only reason I can think of that that would happen is that you have some contrib or custom module installed that does something special for uid=1.

It'd be great to know if you can reproduce this with "vanilla Drupal" (i.e. just Drupal core + JSON:API). If you can, it should also be easy to write a regression test (which I will then be able to do for you, unless you want to of course!).

schlaukopf’s picture

StatusFileSize
new916.22 KB

Sorry I have been so busy last weeks, that I haven't had time to write the regression test. I will try next weekend, so if you can help me before, that would be awesome, but anyway I just spin off an env to test it with the latest Drupal (standard profile) and enabling additionally just jsonapi.
Same behavior as described before.

Uid=1
curl -X POST \
  https://testingjsonapi2zfnmvstkd6.devcloud.acquia-sites.com/jsonapi/block_content/basic \
  -H 'Accept: application/vnd.api+json' \
  -H 'Authorization: Basic YWRtaW46YWRtaW4=' \
  -H 'Content-Type: application/vnd.api+json' \
  -d '{
    "data": {
        "type": "block_content--basic",
        "attributes": {
            "info": "Testing block"
        }
    }
}'

A user with Administrator rol 
curl -X POST \
  https://testingjsonapi2zfnmvstkd6.devcloud.acquia-sites.com/jsonapi/block_content/basic \
  -H 'Accept: application/vnd.api+json' \
  -H 'Authorization: Basic YWRtaW5pc3RyYXRvcjphZG1pbmlzdHJhdG9y' \
  -H 'Content-Type: application/vnd.api+json' \
  -d '{
    "data": {
        "type": "block_content--basic",
        "attributes": {
            "info": "Testing block"
        }
    }
}'

A user with a different rol with “Administer blocks” permission
curl -X POST \
  https://testingjsonapi2zfnmvstkd6.devcloud.acquia-sites.com/jsonapi/block_content/basic \
  -H 'Accept: application/vnd.api+json' \
  -H 'Authorization: Basic dXNlcnRlc3Rlcjp1c2VydGVzdGVy' \
  -H 'Content-Type: application/vnd.api+json' \
  -d '{
    "data": {
        "type": "block_content--basic",
        "attributes": {
            "info": "Testing block"
        }
    }
}'

Screenshot

schlaukopf’s picture

StatusFileSize
new4.47 KB

@wim-leers Sorry for the delay, this Is the scenario

gabesullice’s picture

Status: Postponed (maintainer needs more info) » Active

Thanks for providing a regression test!

wim leers’s picture

Status: Active » Postponed (maintainer needs more info)

Indeed, thanks!

-'{"jsonapi":{"version":"1.0","meta":{"links":{"self":{"href":"http:\/\/jsonapi.org\/format\/1.0\/"}}}},"errors":[{"title":"Unprocessable Entity","status":"422","detail":"info: A custom block with block description Basic block 1 already exists.","source":{"pointer":"\/data\/attributes\/info"}}]}'
+'{"jsonapi":{"version":"1.0","meta":{"links":{"self":{"href":"http:\/\/jsonapi.org\/format\/1.0\/"}}}},"errors":[{"title":"Unprocessable Entity","status":"422","detail":"info: A custom block with block description Basic block 1 already exists.","source":{"file":"\/var\/www\/html\/modules\/contrib\/jsonapi\/src\/Entity\/EntityValidationTrait.php","line":59,"pointer":"\/data\/attributes\/info"},"meta":{"exception":"Drupal\\jsonapi\\Exception\\UnprocessableHttpEntityException: Unprocessable Entity: validation failed. in \/var\/www\/html\/modules\/contrib\/jsonapi\/src\/Entity\/EntityValidationTrait.php:59\nStack trace:\n#0 

Looks like the answer is clear though: one includes a stack trace, the other doesn't. They both result in the exact same error — fortunately! And they also both have an error object.

The problem you're running into is just that the block descriptions need to be unique.

However, you said that the error object was missing in some cases. Well … I think that just got fixed: #3042124: [regression] Empty response body when user is an administrator and an exception is thrown; some traces cannot be encoded because of recursion detection.. Could you please update to 8.x-2.x, commit 52534b2381c098a002075e4f3fadd9c998e0de8d and try again? Thanks!

wim leers’s picture

Title: [upstream] 422 unprocessable entity when trying to create a block content » 422 unprocessable entity when trying to create a block content
Issue tags: -Needs upstream bugfix

It's now looking like this won't need an upstream bugfix.