Conversation
|
Warning Rate limit exceeded
⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. 📝 Walkthrough📝 Walkthrough🚥 Pre-merge checks | ✅ 3 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
The utopia-php/base:php-8.4-0.2.1 image doesn't exist on Docker Hub, causing the CI Docker build to fail. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This reverts commit 2aa26e6.
Changed from utopia-php/base to appwrite/utopia-base. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Temporary debug to identify cache vs DB data differences. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/Database/Database.php (1)
5699-5705:⚠️ Potential issue | 🟠 MajorRemove or gate the debug log to avoid leaking data.
Line 5704 logs raw values (including potential PII) and could flood logs; please remove or guard behind a debug flag/level.🧹 Suggested change (remove debug log)
- error_log("DEBUG shouldUpdate: key={$key} type_new=" . gettype($value) . " type_old=" . gettype($oldValue) . " val_new=" . json_encode($value) . " val_old=" . json_encode($oldValue));
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
When a document goes through cache (JSON serialize/deserialize), float values like 1.0 become int 1. PHP strict comparison then incorrectly detects a change, triggering unnecessary UPDATE permission checks. Use loose numeric comparison to handle this edge case. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add small sleep between document create and update to ensure timestamps differ in millisecond-precision datetime checks. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Fix all issues with AI agents
In `@src/Database/Database.php`:
- Around line 5703-5706: The numeric-equality shortcut using is_numeric($value)
&& is_numeric($oldValue) in Database::... lets numeric-like strings (e.g. "01"
vs "1") bypass $shouldUpdate authorization; restrict the shortcut so it only
applies to true numeric scalars (ints/floats) or to attributes whose declared
type is numeric: check scalar types (e.g. is_int/is_float) or the attribute
metadata before continuing, and only then continue; otherwise fall back to the
normal equality/authorization path that respects $shouldUpdate. Ensure you
update the condition that references $value, $oldValue and is_numeric so it
never skips authorization for string values.
In `@tests/e2e/Adapter/Scopes/DocumentTests.php`:
- Line 5924: The test currently calls \usleep(2000) to try to force an updatedAt
change which is flaky across adapters; replace this single microsecond sleep by
waiting until the timestamp actually changes (either use sleep(1) to wait at
least one second or implement a short loop that reloads the document and breaks
when updatedAt !== createdAt, with a reasonable timeout) in the test that
contains the \usleep(2000) call so the assertion comparing createdAt and
updatedAt is deterministic.
|
|
||
| $newUpdatedAt = $doc11->getUpdatedAt(); | ||
|
|
||
| \usleep(2000); // Ensure updatedAt timestamp differs from creation time |
There was a problem hiding this comment.
Avoid flaky timestamp comparisons across adapters.
A 2ms sleep may not advance $updatedAt on adapters with second/millisecond precision, making the subsequent assertion non-deterministic. Consider sleeping at least a second (or looping until the timestamp changes).
🛠️ Suggested fix
- \usleep(2000); // Ensure updatedAt timestamp differs from creation time
+ // Some adapters only store timestamps with second precision.
+ \usleep(1_100_000); // Ensure updatedAt timestamp differs from creation time📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| \usleep(2000); // Ensure updatedAt timestamp differs from creation time | |
| // Some adapters only store timestamps with second precision. | |
| \usleep(1_100_000); // Ensure updatedAt timestamp differs from creation time |
🤖 Prompt for AI Agents
In `@tests/e2e/Adapter/Scopes/DocumentTests.php` at line 5924, The test currently
calls \usleep(2000) to try to force an updatedAt change which is flaky across
adapters; replace this single microsecond sleep by waiting until the timestamp
actually changes (either use sleep(1) to wait at least one second or implement a
short loop that reloads the document and breaks when updatedAt !== createdAt,
with a reasonable timeout) in the test that contains the \usleep(2000) call so
the assertion comparing createdAt and updatedAt is deterministic.
Apply casting() to the merged document before comparing with $old. This normalizes types (e.g. int 1 back to float 1.0) so the comparison against $old (which was cast during getDocument) uses consistent types. Fixes false-positive change detection caused by JSON cache round-trips degrading float types to int. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Cast individual values to their declared attribute type before comparing with $old, skipping Operator instances. This normalizes types degraded by cache JSON round-trips (e.g. float 1.0 → int 1) without affecting the document that gets persisted. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/Database/Database.php (1)
5604-5717:⚠️ Potential issue | 🟠 MajorType-aware comparison can misfire for array attributes and uncasted old values.
Casting only$value(and without array awareness) can force$shouldUpdate=truefor equal arrays or when$oldValueis still string/uncast, leading to unnecessary updates and stricter permission checks. Consider tracking the array flag and casting both sides only for scalar attributes.🔧 Suggested adjustment (array-aware + symmetric casting)
- $attributeTypes = []; - foreach ($collection->getAttribute('attributes', []) as $attr) { - $attributeTypes[$attr['$id'] ?? ''] = $attr['type'] ?? ''; - } + $attributeTypes = []; + foreach ($collection->getAttribute('attributes', []) as $attr) { + $attrId = $attr['$id'] ?? null; + if ($attrId !== null) { + $attributeTypes[$attrId] = [ + 'type' => $attr['type'] ?? null, + 'array' => (bool)($attr['array'] ?? false), + ]; + } + } $oldValue = $old->getAttribute($key); // Cast value to attribute type for consistent comparison // (e.g. cache JSON round-trip turns float 1.0 into int 1) - $attrType = $attributeTypes[$key] ?? null; - if ($attrType !== null && !\is_null($value) && !($value instanceof Operator)) { - $value = match ($attrType) { - self::VAR_FLOAT => (float)$value, - self::VAR_INTEGER => (int)$value, - self::VAR_BOOLEAN => (bool)$value, - default => $value, - }; - } + $attrMeta = $attributeTypes[$key] ?? null; + if ($attrMeta && !$attrMeta['array'] && !\is_null($value) && !($value instanceof Operator)) { + $cast = fn ($v) => match ($attrMeta['type']) { + self::VAR_FLOAT => (float)$v, + self::VAR_INTEGER => (int)$v, + self::VAR_BOOLEAN => (bool)$v, + default => $v, + }; + $value = $cast($value); + if ($oldValue !== null) { + $oldValue = $cast($oldValue); + } + }
Cast both $value and $oldValue by attribute type before comparison to handle adapters like MongoDB that don't cast floats on read. Add usleep before doc4 update to prevent same-millisecond timestamps. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Summary by CodeRabbit
Bug Fixes
Tests
Chores