{"record":{"id":"915bc82b06b7b725","repo":"mongodb/laravel-mongodb","slug":"cannot-have-both-s-and-s-fields","errorCode":null,"errorMessage":"Cannot have both \"%s\" and \"%s\" fields.","messagePattern":"Cannot have both \"(.+?)\" and \"(.+?)\" fields\\.","errorType":"exception","errorClass":"InvalidArgumentException","httpStatus":null,"severity":"error","filePath":"src/Query/Grammar.php","lineNumber":66,"sourceCode":"        if (array_key_exists('id', $values) && ($root || $this->connection->getRenameEmbeddedIdField())) {\n            if (array_key_exists('_id', $values) && $values['id'] !== $values['_id']) {\n                throw new InvalidArgumentException('Cannot have both \"id\" and \"_id\" fields.');\n            }\n\n            $values['_id'] = $values['id'];\n            unset($values['id']);\n        }\n\n        foreach ($values as $key => $value) {\n            if (! is_string($key)) {\n                continue;\n            }\n\n            // \"->\" arrow notation for subfields is an alias for \".\" dot notation\n            if (str_contains($key, '->')) {\n                $newKey = str_replace('->', '.', $key);\n                if (array_key_exists($newKey, $values) && $value !== $values[$newKey]) {\n                    throw new InvalidArgumentException(sprintf('Cannot have both \"%s\" and \"%s\" fields.', $key, $newKey));\n                }\n\n                $values[$newKey] = $value;\n                unset($values[$key]);\n                $key = $newKey;\n            }\n\n            // \".id\" subfield are alias for \"._id\"\n            if (str_ends_with($key, '.id') && $this->connection->getRenameEmbeddedIdField()) {\n                $newKey = substr($key, 0, -3) . '._id';\n                if (array_key_exists($newKey, $values) && $value !== $values[$newKey]) {\n                    throw new InvalidArgumentException(sprintf('Cannot have both \"%s\" and \"%s\" fields.', $key, $newKey));\n                }\n\n                $values[$newKey] = $value;\n                unset($values[$key]);\n            }\n        }","sourceCodeStart":48,"sourceCodeEnd":84,"githubUrl":"https://github.com/mongodb/laravel-mongodb/blob/0634653039468ceb0268a69192bdac64469ed043/src/Query/Grammar.php#L48-L84","documentation":"The grammar rewrites the '->' arrow notation subfield alias into '.' dot notation. If after the rewrite the target dotted key already exists in the same array with a different value, both entries would conflict, so an InvalidArgumentException naming both keys is thrown.","triggerScenarios":"Passing a payload to prepareFieldsForQuery (via insert/create/update attributes) containing e.g. both 'address->city' and 'address.city' keys with different values.","commonSituations":"Mixing Laravel dot/arrow syntax in nested attribute arrays; copying field definitions from two code styles; template-built payloads where some keys use '->' and others use '.'.","solutions":["Use one notation consistently: pick 'address.city' (dot) or 'address->city' (arrow), not both","Remove the duplicate key whose value is wrong before building the payload","Make both key values identical if the duplication is intentional (the alias is then applied without error)","Add a lint rule or helper that normalizes '->' to '.' in payload keys"],"exampleFix":"// before\n$data = ['address->city' => 'Lyon', 'address.city' => 'Paris'];\nModel::create($data);\n// after\n$data = ['address.city' => 'Paris'];\nModel::create($data);","handlingStrategy":"validation","validationCode":"foreach ($data as $k => $v) {\n    if (str_contains($k, '->')) {\n        $dot = str_replace('->', '.', $k);\n        if (array_key_exists($dot, $data) && $v !== $data[$dot]) {\n            throw new InvalidArgumentException(\"Conflicting keys '$k' and '$dot'\");\n        }\n    }\n}","typeGuard":"function hasArrowDotConflict(array $values): bool {\n    foreach ($values as $k => $v) {\n        if (is_string($k) && str_contains($k, '->')) {\n            $dot = str_replace('->', '.', $k);\n            if (array_key_exists($dot, $values) && $v !== $values[$dot]) return true;\n        }\n    }\n    return false;\n}","tryCatchPattern":"try {\n    $model->create($data);\n} catch (\\InvalidArgumentException $e) {\n    if (str_contains($e->getMessage(), 'Cannot have both')) {\n        $data = normalizeArrowKeys($data); // replace '->' with '.'\n        $model->create($data);\n    } else { throw $e; }\n}","preventionTips":["Standardize on dot notation for nested fields in your codebase","Normalize keys with a helper before building attribute arrays","Lint for mixed '->' and '.' keys in payload construction"],"tags":["php","mongodb","query-builder","key-conflict"],"backgroundTag":"conflicting-config-options","analyzedSha":"0634653039468ceb0268a69192bdac64469ed043","analyzedAt":"2026-09-15T02:56:37.067Z","contentChangedAt":"2026-09-15T02:56:37.067Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}