question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

The type of the "roles" attribute must be "array", "string" given.

See original GitHub issue

So I have an entity in Api Platform that looks like that:
<?php

		namespace App\Entity;

		use Doctrine\ORM\Mapping as ORM;
		use Symfony\Component\Security\Core\User\UserInterface;

		/**
		 * ApiResource, config in config/api_platform/User.yaml
		 * @ORM\Entity(repositoryClass="App\Repository\UserRepository")
		 */
		class User implements UserInterface
		{
			/**
			 * @ORM\Id()
			 * @ORM\GeneratedValue()
			 * @ORM\Column(type="integer")
			 */
			private $id;

			/**
			 * @ORM\Column(type="string", length=180, unique=true)
			 */
			private $username;

			/**
			 * @ORM\Column(type="json")
			 */
			private $roles = [];

			/**
			 * @var string The hashed password
			 * @ORM\Column(type="string")
			 */
			private $password;

			public function getId(): ?int
			{
				return $this->id;
			}

			/**
			 * A visual identifier that represents this user.
			 *
			 * @see UserInterface
			 */
			public function getUsername(): string
			{
				return (string) $this->username;
			}

			public function setUsername(string $username): self
			{
				$this->username = $username;

				return $this;
			}

			/**
			 * @see UserInterface
			 */
			public function getRoles(): array
			{
				$roles = $this->roles;
				// guarantee every user at least has ROLE_USER
				$roles[] = 'ROLE_USER';

				return array_unique($roles);
			}

			public function setRoles(array $roles): self
			{
				$this->roles = $roles;

				return $this;
			}

			/**
			 * @see UserInterface
			 */
			public function getPassword(): string
			{
				return (string) $this->password;
			}

			public function setPassword(string $password): self
			{
				$this->password = $password;

				return $this;
			}

			/**
			 * @see UserInterface
			 */
			public function getSalt()
			{
				// not needed when using the "bcrypt" algorithm in security.yaml
			}

			/**
			 * @see UserInterface
			 */
			public function eraseCredentials()
			{
				// If you store any temporary, sensitive data on the user, clear it here
				// $this->plainPassword = null;
			}
		}

The config/User.yaml:

		resources:
		  App\Entity\User:
			attributes:
			  access_control: is_granted('ROLE_ADMIN')
			collectionOperations:
			  get:
				method: 'GET'
			itemOperations:
			  get:
				method: 'GET'
			  delete:
				method: 'DELETE'
			  put:
				method: 'PUT'
			  post_users_register:
				method: 'POST'
				path: /users
				controller: App\Controller\RegisterUserController
				defaults:
				  _api_receive: false
				access_control_message: "Only admins can create Users"
			  auth:
				route_name: api_login
				swagger_context:
				  summary: Performs a login attempt, returning a valid token on success
				  parameters:
					- name: username
					  required: true
					  type: string
					  description: "User's username"
					- name: password
					  required: true
					  type: string
					  description: "User's password"
				  responses:
					200:
					  description: "Successful login attempt, returning a new token"
					  schema:
						type: object
						properties:
						  token:
							type: string
						  data:
							type: object
							properties:
							  id:
								type: integer
							  roles:
								type: array
								items:
								  type: string
							  username:
								type: string
					401:
					  description: "Bad credentials"
					  schema:
						type: object
						properties:
						  code:
							type: integer
							example: 401
						  message:
							type: string
							example: "Bad credentials"
				  consumes:
					- "application/json"
				  produces:
					- "application/json"

When I use the api-platform/admin it looks like that when i try to edit an entry react_1 react_2

The docs that i get for this class look like this:

	{
				"@id": "#User",
				"@type": "hydra:Class",
				"rdfs:label": "User",
				"hydra:title": "User",
				"hydra:supportedProperty": [
					{
						"@type": "hydra:SupportedProperty",
						"hydra:property": {
							"@id": "#User/username",
							"@type": "rdf:Property",
							"rdfs:label": "username",
							"domain": "#User",
							"range": "xmls:string"
						},
						"hydra:title": "username",
						"hydra:required": false,
						"hydra:readable": true,
						"hydra:writable": true
					},
					{
						"@type": "hydra:SupportedProperty",
						"hydra:property": {
							"@id": "#User/roles",
							"@type": "rdf:Property",
							"rdfs:label": "roles",
							"domain": "#User"
						},
						"hydra:title": "roles",
						"hydra:required": false,
						"hydra:readable": true,
						"hydra:writable": true
					},
					{
						"@type": "hydra:SupportedProperty",
						"hydra:property": {
							"@id": "#User/password",
							"@type": "rdf:Property",
							"rdfs:label": "password",
							"domain": "#User",
							"range": "xmls:string"
						},
						"hydra:title": "password",
						"hydra:required": false,
						"hydra:readable": true,
						"hydra:writable": true,
						"hydra:description": "The hashed password"
					},
					{
						"@type": "hydra:SupportedProperty",
						"hydra:property": {
							"@id": "#User/salt",
							"@type": "hydra:Link",
							"rdfs:label": "salt",
							"domain": "#User"
						},
						"hydra:title": "salt",
						"hydra:required": false,
						"hydra:readable": true,
						"hydra:writable": false
					}
				],
				"hydra:supportedOperation": [
					{
						"@type": [
							"hydra:Operation",
							"schema:FindAction"
						],
						"hydra:method": "GET",
						"hydra:title": "Retrieves User resource.",
						"rdfs:label": "Retrieves User resource.",
						"returns": "#User"
					},
					{
						"@type": [
							"hydra:Operation",
							"schema:DeleteAction"
						],
						"hydra:method": "DELETE",
						"hydra:title": "Deletes the User resource.",
						"rdfs:label": "Deletes the User resource.",
						"returns": "owl:Nothing"
					},
					{
						"@type": [
							"hydra:Operation",
							"schema:ReplaceAction"
						],
						"expects": "#User",
						"hydra:method": "PUT",
						"hydra:title": "Replaces the User resource.",
						"rdfs:label": "Replaces the User resource.",
						"returns": "#User"
					},
					{
						"@type": [
							"hydra:Operation",
							"schema:CreateAction"
						],
						"expects": "#User",
						"hydra:method": "POST",
						"hydra:title": "Creates a User resource.",
						"rdfs:label": "Creates a User resource.",
						"returns": "#User"
					},
					{
						"@type": [
							"hydra:Operation",
							"schema:CreateAction"
						],
						"expects": "#User",
						"hydra:method": "POST",
						"hydra:title": "Creates a User resource.",
						"rdfs:label": "Creates a User resource.",
						"returns": "#User"
					}
				],
				"hydra:description": "ApiResource, config in config/api_platform/User.yaml"
			},

And when I try to edit the entity I get The type of the "roles" attribute must be "array", "string" given.. Dosn’t matter what i type into that field. I’m using the latest Api Platform and the latest Api Platofrm Admin. Anyone has an idea why is this happening? I have the same issue with other entities that I use in my project that use json/array ORM type.

The server code that i use is avaliable at: https://github.com/Nykilor/telefony-srv

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Comments:5 (1 by maintainers)

github_iconTop GitHub Comments

10reactions
ldbglobecommented, Nov 25, 2019

A simple solution is to override JsonLd Context using anotation in your Api-Platform Entity

    /**
     * @ORM\Column(type="simple_array")
     * @ApiProperty(
     *     attributes={
     *         "jsonld_context"={
     *             "@type"="http://www.w3.org/2001/XMLSchema#array",
     *         }
     *     }
     * )
     */
    private $my_simple_array_field= [];
0reactions
knarficiouscommented, Jul 29, 2020

@ldbglobe Thank you, that works fine

Read more comments on GitHub >

github_iconTop Results From Across the Web

Argument must be of type ?array, string given, called in ...
i don't understand my error on API Plateform. Doctrine\ORM\Mapping\ManyToOne::__construct(): Argument #2 ($cascade) must be of type ?array, ...
Read more >
The type of the attribute must be bool, string given-symfony
Coding example for the question Symfony - Validation: The type of the attribute must be bool, string given-symfony.
Read more >
Array - Sanity.io
The of property specifies which value types the array may hold. Properties. REQUIREDtypestring. Value must be set to array .
Read more >
Arrays | Elasticsearch Guide [8.5] | Elastic
In Elasticsearch, there is no dedicated array data type. Any field can contain zero or more values by default, however, all values in...
Read more >
Eloquent: Serialization - The PHP Framework For Web Artisans
To convert a model and its loaded relationships to an array, you should use the toArray method. This method is recursive, so all...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found