Skip to content

Conversation

@sktbrd
Copy link

@sktbrd sktbrd commented Feb 6, 2026

Problem

Image uploads were failing on some devices with generic error messages. The issue was traced to commit 59f6976 which removed the file existence validation before attempting JPEG conversion.

Root Cause

Without the file existence check, if the image URI is invalid (permissions issue, cache cleared, etc.), the ImageManipulator fails with an unclear error instead of a helpful message.

Solution

Restored the file existence check in image-converter.ts that validates the file exists before attempting conversion:

const fileInfo = await FileSystem.getInfoAsync(uri);
if (!fileInfo.exists) {
  throw new Error(`Image file not found: ${uri}`);
}

Testing

  • Test image upload on iOS (HEIC and JPEG)
  • Test image upload on Android
  • Test with large images (>10MB)
  • Verify video upload still works (unaffected)

Related

Summary by CodeRabbit

  • Bug Fixes

    • Fixed mobile image upload failures by adding a pre-conversion check to ensure image files exist before JPEG conversion, preventing upload errors.
  • Documentation

    • Added a short document describing the issue, the verification-based fix, and a testing checklist for mobile image uploads.

- Add FileSystem.getInfoAsync check before ImageManipulator
- Provides clear error message when file is missing/inaccessible
- Fixes image upload failures on some devices

Reverts part of 59f6976 that removed this validation
@coderabbitai
Copy link

coderabbitai bot commented Feb 6, 2026

📝 Walkthrough

Walkthrough

Restores a missing file-existence check in the image converter and documents the fix. Adds an expo-file-system import and a pre-conversion check that throws if the input file is absent; includes a new PR_DESCRIPTION.md describing root cause, solution, and tests.

Changes

Cohort / File(s) Summary
Documentation
PR_DESCRIPTION.md
Adds a document describing the mobile image upload failure, root cause (removed file-existence validation), the fix (restore check), a code snippet, testing checklist, and related links.
Image Converter Fix
lib/upload/image-converter.ts
Adds expo-file-system import and a pre-check in convertToJPEG using FileSystem.getInfoAsync(uri) to verify file existence and throw if missing before conversion.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~8 minutes

Poem

🐰 I sniffed the path, gave it a peep,
If no file sleeps, I wake and leap,
Convert with care, no silent flop—
Now uploads hum and never stop! 📸✨

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: restoring a file existence check before image conversion to fix mobile image uploads.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feature/fix-mobile-image-upload

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@lib/upload/image-converter.ts`:
- Line 2: The import "import * as FileSystem from 'expo-file-system'" in
lib/upload/image-converter.ts requires adding expo-file-system to package.json
dependencies; add "expo-file-system" to the dependencies section (use the
matching version for your Expo SDK), run npm/yarn install to update node_modules
and the lockfile, and commit the updated package.json and
package-lock.json/yarn.lock so the runtime can resolve the FileSystem import.
🧹 Nitpick comments (3)
lib/upload/image-converter.ts (2)

44-48: Good restore of the file existence pre-check — but note the error is double-wrapped.

The existence check itself is correct and addresses the root cause. However, the throw on line 47 is inside the try block, so it will be caught by the catch on line 67 and re-wrapped as:

Failed to convert image: Image file not found: <uri>

This is still informative, but if the intent is to surface a distinct "file not found" error to callers (e.g., to show different UI), they won't be able to distinguish it from a conversion failure without parsing the message string.

Consider either re-throwing the file-not-found error before the try, or checking for it in the catch to avoid wrapping:

Option: move the check before the try block
 export async function convertToJPEG(
   uri: string,
   quality: number = 0.8
 ): Promise<ConvertedImage> {
+  // Verify file exists before attempting conversion
+  const fileInfo = await FileSystem.getInfoAsync(uri);
+  if (!fileInfo.exists) {
+    throw new Error(`Image file not found: ${uri}`);
+  }
+
   try {
-    // Verify file exists before attempting conversion
-    const fileInfo = await FileSystem.getInfoAsync(uri);
-    if (!fileInfo.exists) {
-      throw new Error(`Image file not found: ${uri}`);
-    }
-
     // Convert to JPEG using ImageManipulator

Note: Moving the check outside try means a failure in getInfoAsync itself (e.g., invalid URI scheme) would become an unhandled rejection. You'd need to decide which trade-off is preferable for your error-reporting strategy.


81-89: Promise.all will fail fast on the first bad image — consider if that's desired.

If one URI in the batch is invalid, the entire batch rejects immediately. If partial results are useful, Promise.allSettled would allow the caller to handle per-image failures. This is pre-existing behavior and not introduced by this PR, so just flagging for awareness.

PR_DESCRIPTION.md (1)

1-27: Clear and well-structured PR documentation.

One minor consideration: committing a PR_DESCRIPTION.md to the repo means it will persist after the PR is merged. If this is intended as living documentation (e.g., an ADR or changelog entry), that's fine. If it's only meant to accompany the PR, the content might be better suited to the PR body on GitHub to avoid accumulating stale markdown files over time.

@@ -1,4 +1,5 @@
import * as ImageManipulator from 'expo-image-manipulator';
import * as FileSystem from 'expo-file-system';
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Check if expo-file-system is listed as a dependency in package.json
echo "=== Searching for package.json files ==="
find . -name 'package.json' -type f | head -5

echo ""
echo "=== Checking for expo-file-system in package.json ==="
fd -g 'package.json' --max-depth 3 --exec cat {} \; | grep -i 'expo-file-system' || echo "No match found"

echo ""
echo "=== Full dependencies section from package.json ==="
fd -g 'package.json' --max-depth 3 --exec jq '.dependencies, .devDependencies' {} \; 2>/dev/null || echo "Could not parse as JSON"

Repository: SkateHive/mobileapp

Length of output: 1839


Add expo-file-system to package.json dependencies.

The code imports expo-file-system on line 2, but this package is not declared in package.json. This will cause a runtime failure. Add it to the dependencies section alongside the other expo packages.

🤖 Prompt for AI Agents
In `@lib/upload/image-converter.ts` at line 2, The import "import * as FileSystem
from 'expo-file-system'" in lib/upload/image-converter.ts requires adding
expo-file-system to package.json dependencies; add "expo-file-system" to the
dependencies section (use the matching version for your Expo SDK), run npm/yarn
install to update node_modules and the lockfile, and commit the updated
package.json and package-lock.json/yarn.lock so the runtime can resolve the
FileSystem import.

@sktbrd
Copy link
Author

sktbrd commented Feb 7, 2026

Re: expo-file-system dependency

@coderabbitai This is a false positive. expo-file-system is already used in this codebase:

// lib/upload/image-upload.ts (line 1)
import { File } from 'expo-file-system';

The package is available as a transitive dependency through the expo package in Expo SDK 54. No additional entry in package.json is required.

The import was also previously used in this same file before commit 59f6976 removed it.

@coderabbitai
Copy link

coderabbitai bot commented Feb 7, 2026

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash

# Check if expo-file-system is imported in lib/upload/image-upload.ts
echo "=== Checking lib/upload/image-upload.ts for expo-file-system import ==="
cat lib/upload/image-upload.ts | head -20

echo -e "\n=== Checking lib/upload/image-converter.ts current state ==="
cat lib/upload/image-converter.ts

echo -e "\n=== Checking package.json for expo package ==="
cat package.json | grep -A2 -B2 "expo"

echo -e "\n=== Searching for other expo-file-system usage in codebase ==="
rg "expo-file-system" -n -C2

Length of output: 10046


@sktbrd, you're absolutely correct! I verified your claims and confirmed:

  1. expo-file-system is imported in lib/upload/image-upload.ts (line 1)
  2. ✅ The project uses Expo SDK 54 ("expo": "~54.0.9" in package.json)
  3. expo-file-system@19.0.14 is present in pnpm-lock.yaml as a transitive dependency through the expo package

This is indeed a false positive. The expo-file-system package is a standard Expo SDK module that's automatically available through the main expo package and doesn't require an explicit entry in package.json. Thank you for the clarification!

(\_/)
(^.^) - noted!
(")_(")

✏️ Learnings added
Learnt from: sktbrd
URL: https://github.com/SkateHive/mobileapp/pull/3

Timestamp: 2026-02-07T03:48:14.477Z
Learning: In Expo SDK 54 projects, `expo-file-system` is available as a transitive dependency through the main `expo` package and doesn't require an explicit entry in package.json. The package is already used in lib/upload/image-upload.ts.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.

@sktbrd
Copy link
Author

sktbrd commented Feb 7, 2026

@bgrana75

image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant