[Bug]: trailing comma issue
What happened?
i get this error when i go to /docs/api.json path
"Error when analyzing route 'GET api/v1/user' (App\Http\Controllers\AuthController@me): A trailing comma is not allowed here on line 3 – /var/www/html/vendor/nik ▶"
php -v
PHP 8.3.8 (cli) (built: Jun 13 2024 05:41:23) (NTS)
Copyright (c) The PHP Group
Zend Engine v4.3.8, Copyright (c) Zend Technologies
with Zend OPcache v8.3.8, Copyright (c), by Zend Technologies
with Xdebug v3.4.5, Copyright (c) 2002-2025, by Derick Rethan
composer show | grep dedoc
dedoc/scramble 0.12.36 Automatic generation of API documentation for Laravel applications.
dedoc/scramble-pro 0.7.18 Scramble PRO
How to reproduce the bug
a trailing comma issue
Package Version
.
PHP Version
.
Laravel Version
Laravel Framework 11.46.1
Which operating systems does with happen with?
macOS
Notes
No response
@slnw can you please share the source of AuthController@me method?
/**
* Get the authenticated User.
*
* @return UserData
*/
public function me()
{
return UserData::from(auth()->user())->include('current_team.balance');
}
UserData:
<?php
namespace App\Domain\Platform\Data;
use App\Domain\Campaigns\Domains\Models\DomainAccount;
use App\Domain\Platform\Models\User;
use App\Infra\Scramble\LaravelDataFakeInterface;
use Database\Factories\Domain\Platform\Models\UserFactory;
use Spatie\LaravelData\Attributes\Validation\Uuid;
use Spatie\LaravelData\Data;
use Spatie\LaravelData\Lazy;
class UserData extends Data implements LaravelDataFakeInterface
{
public function __construct(
#[Uuid]
public string $id,
public string $name,
public string $email,
public string $created_at,
public ?string $two_factor_confirmed_at,
public ?string $profile_photo_path,
public ?string $platform_domain_account_id,
public TeamData|Lazy|null $current_team,
public ?string $role = null,
public ?string $platform_role = null,
public ?array $meta = null
)
{
}
public static function fromModel(User $user): self
{
$team = $user->teams()->find($user->current_team_id);
return self::from([
'platform_domain_account_id' => DomainAccount::getPlatformAccount()?->id,
'current_team' => Lazy::create(
fn() => $team !== null ? UserTeamData::fromModel($team) : null
),
'role' => $user->membership?->role,
...$user->toArray(),
'platform_role' => $user->platform_role
]);
}
public static function fake(): self
{
return self::from(UserFactory::new()->make());
}
}
<?php
namespace App\Domain\Platform\Data;
use App\Domain\Platform\Models\Team;
use App\Infra\Scramble\LaravelDataFakeInterface;
use Spatie\LaravelData\Data;
use Spatie\LaravelData\Lazy;
class TeamData extends Data implements LaravelDataFakeInterface
{
public function __construct(
public string $id,
public string $name,
public string $created_at,
public ?TeamMetaData $meta,
public float|Lazy|null $balance = null
) {
}
public static function fromModel(Team $team)
{
return new self(
id: $team->id,
name: $team->name,
created_at: $team->created_at,
meta: TeamMetaData::from($team->meta),
balance: Lazy::create(fn() => $team->platformBalance())
);
}
public static function fake(): self
{
return self::from([...Team::factory()->make()->getAttributes(), 'balance' => 1000]);
}
}
etc' etc'
@slnw would you mind sharing a bit a stack trace entries as well?
Error when analyzing route 'GET api/v1/user' (App\Http\Controllers\AuthController@me): A trailing comma is not allowed here on line 3 – /var/www/html/vendor/nikic/php-parser/lib/PhpParser/Parser/Php8.php on line 1382
\
Parser
\
Php8
: 1382
PhpParser\Parser\{closure}
PhpParser
\
ParserAbstract
: 325
doParse
PhpParser
\
ParserAbstract
: 187
parse
Dedoc
\
Scramble
\
Infer
\
Services
\
FileParser
: 36
parseContent
Dedoc
\
Scramble
\
Infer
\
Reflector
\
PropertyReflector
: 175
getAstNode
Dedoc
\
Scramble
\
Infer
\
Analyzer
\
PropertyAnalyzer
: 47
getDefaultTypeFromAst
Dedoc
\
Scramble
\
Infer
\
Analyzer
\
PropertyAnalyzer
: 36
getDefaultType
Dedoc
\
Scramble
\
Infer
\
Analyzer
\
ClassAnalyzer
: 83
analyze
Dedoc
\
Scramble
\
Infer
\
Scope
\
Index
: 47
getClass
Dedoc
\
Scramble
\
Infer
\
Services
\
ReferenceTypeResolver
: 312
resolveNewCallReferenceType
Dedoc
\
Scramble
\
Infer
\
Services
\
ReferenceTypeResolver
: 79
doResolve
Dedoc
\
Scramble
\
Infer
\
Services
\
ReferenceTypeResolver
: 59
Dedoc\Scramble\Infer\Services\{closure}
Dedoc
\
Scramble
\
Support
\
Type
\
TypeWalker
: 118
map
Dedoc
\
Scramble
\
Infer
\
Services
\
ReferenceTypeResolver
: 59
Dedoc\Scramble\Infer\Services\{closure}
Dedoc
\
Scramble
\
Infer
\
Services
\
RecursionGuard
: 35
run
Dedoc
\
Scramble
\
Infer
\
Services
\
ReferenceTypeResolver
: 57
resolve
Dedoc
\
ScramblePro
\
Extensions
\
LaravelData
\
DataPropertySchemaTransformer
: 174
createDataType
Dedoc
\
ScramblePro
\
Extensions
\
LaravelData
\
DataPropertySchemaTransformer
: 148
transformLaravelDataTypeToInferType
Dedoc
\
ScramblePro
\
Extensions
\
LaravelData
\
DataPropertySchemaTransformer
: 81
toAllSchemas
Dedoc
\
ScramblePro
\
Extensions
\
LaravelData
\
DataToSchemaTransformer
: 47
transform
Dedoc
\
ScramblePro
\
Extensions
\
LaravelData
\
Generator
\
DataSchemaExtension
: 61
toSchema
Dedoc
\
Scramble
\
Support
\
Generator
\
TypeTransformer
: 277
Dedoc\Scramble\Support\Generator\{closure}
Illuminate
\
Support
\
Collection
: 822
reduce
Dedoc
\
Scramble
\
Support
\
Generator
\
TypeTransformer
: 276
handleUsingExtensions
Dedoc
\
Scramble
\
Support
\
Generator
\
TypeTransformer
: 232
transform
Dedoc
\
ScramblePro
\
Extensions
\
LaravelData
\
DataPropertySchemaTransformer
: 85
toAllSchemas
Dedoc
\
ScramblePro
\
Extensions
\
LaravelData
\
DataToSchemaTransformer
: 47
transform
Dedoc
\
ScramblePro
\
Extensions
\
LaravelData
\
Generator
\
DataSchemaExtension
: 61
toSchema
Dedoc
\
Scramble
\
Support
\
Generator
\
TypeTransformer
: 277
Dedoc\Scramble\Support\Generator\{closure}
Illuminate
\
Support
\
Collection
: 822
reduce
Dedoc
\
Scramble
\
Support
\
Generator
\
TypeTransformer
: 276
handleUsingExtensions
Dedoc
\
Scramble
\
Support
\
Generator
\
TypeTransformer
: 232
transform
Dedoc
\
ScramblePro
\
Extensions
\
LaravelData
\
DataPropertySchemaTransformer
: 85
toAllSchemas
Dedoc
\
ScramblePro
\
Extensions
\
LaravelData
\
DataToSchemaTransformer
: 47
transform
Dedoc
\
ScramblePro
\
Extensions
\
LaravelData
\
Generator
\
DataSchemaExtension
: 61
toSchema
Dedoc
\
Scramble
\
Support
\
Generator
\
TypeTransformer
: 277
Dedoc\Scramble\Support\Generator\{closure}
Illuminate
\
Support
\
Collection
: 822
reduce
Dedoc
\
Scramble
\
Support
\
Generator
\
TypeTransformer
: 276
handleUsingExtensions
Dedoc
\
Scramble
\
Support
\
Generator
\
TypeTransformer
: 232
transform
Dedoc
\
ScramblePro
\
Extensions
\
LaravelData
\
Generator
\
DataSchemaExtension
: 68
toResponse
Dedoc
\
Scramble
\
Support
\
Generator
\
TypeTransformer
: 354
Dedoc\Scramble\Support\Generator\{closure}
.unknown
0
array_reduce
Dedoc
\
Scramble
\
Support
\
Generator
\
TypeTransformer
: 347
handleResponseUsingExtensions
Dedoc
\
Scramble
\
Support
\
Generator
\
TypeTransformer
: 303
toResponse
.unknown
0
array_map
Illuminate
\
Support
\
Arr
: 609
map
Illuminate
\
Support
\
Collection
: 799
map
Dedoc
\
Scramble
\
Support
\
OperationExtensions
\
ResponseExtension
: 65
collectInferredResponses
Dedoc
\
Scramble
\
Support
\
OperationExtensions
\
ResponseExtension
: 26
handle
Dedoc
\
Scramble
\
Support
\
OperationBuilder
: 37
build
Dedoc
\
Scramble
\
Generator
: 234
routeToOperation
Dedoc
\
Scramble
\
Generator
: 61
Dedoc\Scramble\{closure}
.unknown
0
array_map
Illuminate
\
Support
\
Arr
: 609
map
Illuminate
\
Support
\
Collection
: 799
map
Dedoc
\
Scramble
\
Generator
: 59
__invoke
Dedoc
\
Scramble
\
ScrambleServiceProvider
: 291
Dedoc\Scramble\{closure}
Illuminate
\
Routing
\
CallableDispatcher
: 40
dispatch
Illuminate
\
Routing
\
Route
: 244
runCallable
Illuminate
\
Routing
\
Route
: 215
run
Illuminate
\
Routing
\
Router
: 808
Illuminate\Routing\{closure}
Illuminate
\
Pipeline
\
Pipeline
: 170
Illuminate\Pipeline\{closure}
Illuminate
\
Routing
\
Middleware
\
SubstituteBindings
: 51
handle
Illuminate
\
Pipeline
\
Pipeline
: 209
Illuminate\Pipeline\{closure}
Illuminate
\
View
\
Middleware
\
ShareErrorsFromSession
: 49
handle
Illuminate
\
Pipeline
\
Pipeline
: 209
Illuminate\Pipeline\{closure}
Illuminate
\
Session
\
Middleware
\
StartSession
: 121
handleStatefulRequest
Illuminate
\
Session
\
Middleware
\
StartSession
: 64
handle
Illuminate
\
Pipeline
\
Pipeline
: 209
Illuminate\Pipeline\{closure}
Illuminate
\
Cookie
\
Middleware
\
AddQueuedCookiesToResponse
: 37
handle
Illuminate
\
Pipeline
\
Pipeline
: 209
Illuminate\Pipeline\{closure}
Illuminate
\
Cookie
\
Middleware
\
EncryptCookies
: 75
handle
Illuminate
\
Pipeline
\
Pipeline
: 209
Illuminate\Pipeline\{closure}
Illuminate
\
Pipeline
\
Pipeline
: 127
then
Illuminate
\
Routing
\
Router
: 807
runRouteWithinStack
Illuminate
\
Routing
\
Router
: 786
runRoute
Illuminate
\
Routing
\
Router
: 750
dispatchToRoute
Illuminate
\
Routing
\
Router
: 739
dispatch
Illuminate
\
Foundation
\
Http
\
Kernel
: 201
Illuminate\Foundation\Http\{closure}
Illuminate
\
Pipeline
\
Pipeline
: 170
Illuminate\Pipeline\{closure}
Illuminate
\
Foundation
\
Http
\
Middleware
\
TransformsRequest
: 21
handle
Illuminate
\
Foundation
\
Http
\
Middleware
\
ConvertEmptyStringsToNull
: 31
handle
Illuminate
\
Pipeline
\
Pipeline
: 209
Illuminate\Pipeline\{closure}
Illuminate
\
Foundation
\
Http
\
Middleware
\
TransformsRequest
: 21
handle
Illuminate
\
Foundation
\
Http
\
Middleware
\
TrimStrings
: 51
handle
Illuminate
\
Pipeline
\
Pipeline
: 209
Illuminate\Pipeline\{closure}
Illuminate
\
Http
\
Middleware
\
ValidatePostSize
: 27
handle
Illuminate
\
Pipeline
\
Pipeline
: 209
Illuminate\Pipeline\{closure}
Illuminate
\
Foundation
\
Http
\
Middleware
\
PreventRequestsDuringMaintenance
: 110
handle
Illuminate
\
Pipeline
\
Pipeline
: 209
Illuminate\Pipeline\{closure}
Illuminate
\
Http
\
Middleware
\
HandleCors
: 62
handle
Illuminate
\
Pipeline
\
Pipeline
: 209
Illuminate\Pipeline\{closure}
Illuminate
\
Http
\
Middleware
\
TrustProxies
: 58
handle
Illuminate
\
Pipeline
\
Pipeline
: 209
Illuminate\Pipeline\{closure}
Illuminate
\
Pipeline
\
Pipeline
: 127
then
Illuminate
\
Foundation
\
Http
\
Kernel
: 176
sendRequestThroughRouter
Illuminate
\
Foundation
\
Http
\
Kernel
: 145
handle
public
/
index
.php
: 51
[top]
@slnw I think Scramble fails to analyze a default value of some property, but I don't see any properties in the shared code that would cause this issue.
Can you please also show the source of LaravelDataFakeInterface?
it's not related, i removed all the instances of implements LaravelDataFakeInterface and it still gets this error :/
@slnw Understood.
Can you please help me debug it?
For me to reproduce the core issue, I need to know the class source that causes this issue.
So dumping the class will help.
Can you please replace the line 175 in PropertyReflector (https://github.com/dedoc/scramble/blob/017e4ee31e2b93d93b58f21c08291257352f0719/src/Infer/Reflector/PropertyReflector.php#L175) to this code:
try {
$statements = $this->parser->parseContent($partialClass)->getStatements();
} catch (\Throwable $e) {
dump($e->getMessage());
dump($this->name);
dd($this->getClassReflector()->getSource());
}
And then send me the output of these dumps.
The idea is to get the source of class that causes the issue.
Thanks!
@slnw any updates on this? Have you been able to find the reason or get the source that causes the issue?