<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Hala</title>
    <description>The latest articles on DEV Community by Hala (@hala1_1).</description>
    <link>https://dev.to/hala1_1</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3839172%2F460ce985-9c09-4b3a-aac8-827f388804a2.png</url>
      <title>DEV Community: Hala</title>
      <link>https://dev.to/hala1_1</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/hala1_1"/>
    <language>en</language>
    <item>
      <title>How to Fix Image Upload Failures &amp; 404 Errors in React Native + Express/Multer</title>
      <dc:creator>Hala</dc:creator>
      <pubDate>Fri, 24 Jul 2026 12:07:36 +0000</pubDate>
      <link>https://dev.to/hala1_1/how-to-fix-image-upload-failures-404-errors-in-react-native-expressmulter-3fhb</link>
      <guid>https://dev.to/hala1_1/how-to-fix-image-upload-failures-404-errors-in-react-native-expressmulter-3fhb</guid>
      <description>&lt;p&gt;Uploading images from a React Native (Expo) client to a Node.js/Express backend using Multer is a common task, but it often comes with two frustrating issues:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;TypeError: Network request failed&lt;/code&gt; during the upload process.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;404 Not Found&lt;/code&gt; warnings when trying to render uploaded images in the mobile app.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Here is a breakdown of why these errors happen and how to resolve them cleanly on both the backend and client side.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Error Logs
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Upload Phase Error (React Native Console)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ERROR Upload error: [TypeError: Network request failed]

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. Asset Rendering Phase Warning (Expo / LogBox)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;WARN Unexpected HTTP code Response{protocol=http/1.1, code=404, message=Not Found, url=http://192.168.8.101:8000/uploads/1784893610816-edeedac9.jpeg}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Root Cause Analysis
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Problem 1: Unhandled Missing Upload Directory (&lt;code&gt;ENOENT&lt;/code&gt;)
&lt;/h3&gt;

&lt;p&gt;When using &lt;code&gt;multer.diskStorage&lt;/code&gt;, you specify a target directory like &lt;code&gt;public/uploads&lt;/code&gt;. Multer does not create missing folders automatically. If that folder does not exist on your server when an upload request hits the endpoint, Node.js throws an &lt;code&gt;ENOENT&lt;/code&gt; exception, abruptly closing the socket connection. From the React Native side, this manifests as &lt;code&gt;TypeError: Network request failed&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Problem 2: Incorrect Static File Route Prefix
&lt;/h3&gt;

&lt;p&gt;Using &lt;code&gt;app.use(express.static("public"))&lt;/code&gt; in Express serves the contents of the &lt;code&gt;public&lt;/code&gt; folder directly from the root path (&lt;code&gt;http://IP:PORT/filename.jpg&lt;/code&gt;). If your client tries to fetch &lt;code&gt;http://IP:PORT/uploads/filename.jpg&lt;/code&gt;, Express cannot map the path correctly and returns a &lt;code&gt;404 Not Found&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Problem 3: Android File URI Formatting
&lt;/h3&gt;

&lt;p&gt;Local image URIs retrieved on Android devices often require explicit formatting (&lt;code&gt;uri&lt;/code&gt;, &lt;code&gt;name&lt;/code&gt;, &lt;code&gt;type&lt;/code&gt;) inside &lt;code&gt;FormData&lt;/code&gt; to be parsed properly as a binary stream by &lt;code&gt;fetch&lt;/code&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Solution
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Auto-create Directory in &lt;code&gt;multer.js&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Update your Multer configuration to check for and create the target directory dynamically using the standard &lt;code&gt;fs&lt;/code&gt; module:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;multer&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;multer&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;fs&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;fs&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;path&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;path&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;uploadDir&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;public/uploads&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;fs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;existsSync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;uploadDir&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;fs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;mkdirSync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;uploadDir&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;recursive&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;storage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;multer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;diskStorage&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;destination&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;file&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;cb&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;cb&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;uploadDir&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;filename&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;file&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;cb&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ext&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;extname&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;file&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;originalname&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;.jpg&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nf"&gt;cb&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;()}&lt;/span&gt;&lt;span class="s2"&gt;-&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;round&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;random&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="nx"&gt;e9&lt;/span&gt;&lt;span class="p"&gt;)}${&lt;/span&gt;&lt;span class="nx"&gt;ext&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;upload&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;multer&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;storage&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;upload&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  2. Map Static Route Correctly in &lt;code&gt;server.js&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Explicitly map requests containing the &lt;code&gt;/uploads&lt;/code&gt; prefix to the physical &lt;code&gt;public/uploads&lt;/code&gt; directory on disk:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;express&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;express&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;express&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/uploads&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;express&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;static&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;public/uploads&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  3. Handle Client-Side Uploads in React Native (&lt;code&gt;functions.js&lt;/code&gt;)
&lt;/h3&gt;

&lt;p&gt;Format the image payload cleanly inside &lt;code&gt;FormData&lt;/code&gt; before making the network call:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Platform&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react-native&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;API_URL&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@env&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;uploadImage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;token&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;localUri&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;filename&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;localUri&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;pop&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;profile.jpg&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;match&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="se"&gt;\.(\w&lt;/span&gt;&lt;span class="sr"&gt;+&lt;/span&gt;&lt;span class="se"&gt;)&lt;/span&gt;&lt;span class="sr"&gt;$/&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;exec&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;filename&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;match&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="s2"&gt;`image/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;match&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;image/jpeg&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;fileUri&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Platform&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;OS&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;android&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;localUri&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;localUri&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;file://&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;formData&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;FormData&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nx"&gt;formData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;profilePicture&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;uri&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;fileUri&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;filename&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;authHeader&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;token&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nf"&gt;startsWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Bearer &lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;token&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`Bearer &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;token&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;API_URL&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/user/profile-picture`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;PUT&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;Authorization&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;authHeader&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;Accept&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;application/json&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;formData&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ok&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="s2"&gt;`Server Error: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Upload error:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Verification &amp;amp; Results
&lt;/h2&gt;

&lt;p&gt;Applying these updates addresses the issue on both ends:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The backend responds with HTTP status &lt;code&gt;200 OK&lt;/code&gt; on image upload requests.&lt;/li&gt;
&lt;li&gt;MongoDB stores the reachable absolute URL string.&lt;/li&gt;
&lt;li&gt;Both iOS and Android clients render the updated profile image without broken image icons or caching issues.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;When building mobile apps with React Native and Node.js, ensure your server dynamically verifies target upload paths at runtime, and double-check that Express static route configurations mirror the URL paths requested by the frontend client.&lt;/p&gt;

</description>
      <category>reactnative</category>
      <category>node</category>
      <category>express</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Fixing “Please update Expo Go” error (even when it’s already updated)</title>
      <dc:creator>Hala</dc:creator>
      <pubDate>Tue, 02 Jun 2026 01:49:46 +0000</pubDate>
      <link>https://dev.to/hala1_1/fixing-please-update-expo-go-error-even-when-its-already-updated-ldg</link>
      <guid>https://dev.to/hala1_1/fixing-please-update-expo-go-error-even-when-its-already-updated-ldg</guid>
      <description>&lt;p&gt;While developing a React Native app using Expo, I ran into a really confusing issue.&lt;/p&gt;

&lt;p&gt;Every time I tried to run my project, the app would open normally but immediately show this message inside the app:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;“Please update Expo Go to the latest version from Google Play Store”&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The strange part?&lt;br&gt;
My Expo Go was already updated to the latest version from the Google Play Store.&lt;/p&gt;

&lt;p&gt;I double-checked multiple times, uninstalled and reinstalled it, but the error still kept showing.&lt;/p&gt;




&lt;p&gt;Environment&lt;br&gt;
React Native (Expo)&lt;/p&gt;

&lt;p&gt;Expo SDK (latest at the time of writing)&lt;/p&gt;

&lt;p&gt;Android (Google Play Store version of Expo Go)&lt;/p&gt;

&lt;p&gt;No errors in terminal&lt;/p&gt;




&lt;p&gt;What I tried&lt;/p&gt;

&lt;p&gt;Before finding the actual fix, I tried the usual debugging steps:&lt;/p&gt;

&lt;p&gt;Reinstalling Expo Go from Google Play Store&lt;/p&gt;

&lt;p&gt;Logging out and logging back into Expo&lt;/p&gt;

&lt;p&gt;Reconnecting the project&lt;/p&gt;

&lt;p&gt;Restarting Metro bundler&lt;/p&gt;

&lt;p&gt;Clearing cache and node modules&lt;/p&gt;

&lt;p&gt;Rebuilding the project&lt;/p&gt;

&lt;p&gt;Nothing worked ❌&lt;/p&gt;

&lt;p&gt;Everything looked fine… except the error inside the app.&lt;/p&gt;




&lt;p&gt;The real issue&lt;/p&gt;

&lt;p&gt;The problem wasn’t in my code or Expo setup.&lt;/p&gt;

&lt;p&gt;It was a version mismatch between the Play Store Expo Go build and the required SDK version of my project.&lt;/p&gt;

&lt;p&gt;Even though the app showed as “updated”, it was still not compatible with my project’s Expo SDK version.&lt;/p&gt;




&lt;p&gt;The solution&lt;/p&gt;

&lt;p&gt;Instead of relying on the Play Store version, I installed the latest Expo Go build manually from the official source.&lt;/p&gt;

&lt;p&gt;After installing it manually:&lt;/p&gt;

&lt;p&gt;The app launched successfully&lt;/p&gt;

&lt;p&gt;The error disappeared immediately&lt;/p&gt;

&lt;p&gt;Everything worked as expected&lt;/p&gt;




&lt;p&gt;Key takeaway&lt;/p&gt;

&lt;p&gt;If you ever see this message:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Please update Expo Go…”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;even when your app is already updated from the Play Store:&lt;/p&gt;

&lt;p&gt;👉 Don’t assume it’s actually up to date&lt;br&gt;
👉 Try installing the latest version manually from the official Expo releases instead&lt;/p&gt;

&lt;p&gt;It saved me hours of confusion and debugging.&lt;/p&gt;




&lt;p&gt;Final thoughts&lt;/p&gt;

&lt;p&gt;This was one of those annoying issues where everything looks correct, but the problem is actually in version alignment between tools rather than your code.&lt;/p&gt;

&lt;p&gt;Hopefully this helps someone avoid the same headache 🙂&lt;/p&gt;

</description>
      <category>android</category>
      <category>mobile</category>
      <category>reactnative</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>How Windows Caused a Fatal “typeof” Error in Expo EAS Build — And Why Linux Solved It</title>
      <dc:creator>Hala</dc:creator>
      <pubDate>Mon, 23 Mar 2026 03:26:45 +0000</pubDate>
      <link>https://dev.to/hala1_1/how-windows-caused-a-fatal-typeof-error-in-expo-eas-build-and-why-linux-solved-it-mfl</link>
      <guid>https://dev.to/hala1_1/how-windows-caused-a-fatal-typeof-error-in-expo-eas-build-and-why-linux-solved-it-mfl</guid>
      <description>&lt;p&gt;Introduction&lt;/p&gt;

&lt;p&gt;I recently faced one of the strangest and most frustrating technical issues in my development journey. My mobile application was working perfectly during development, but everything broke when I tried to build the production Android version.&lt;/p&gt;

&lt;p&gt;What made the situation worse was that the error appeared to be unrelated to my code. After several days of troubleshooting, the solution turned out to be something I never expected: the operating system itself.&lt;/p&gt;

&lt;p&gt;This article documents the full technical journey in hopes that it helps any developer facing a similar issue.&lt;/p&gt;




&lt;p&gt;The Fatal Error&lt;/p&gt;

&lt;p&gt;The project ran normally in development mode using Expo. However, when attempting to build the Android production version using EAS Build:&lt;/p&gt;

&lt;p&gt;eas build --platform android --profile production&lt;/p&gt;

&lt;p&gt;The process suddenly stopped and repeatedly produced the following error:&lt;/p&gt;

&lt;p&gt;SyntaxError: Unexpected token 'typeof'&lt;br&gt;
at Object.compileFunction (node:vm:360:18)&lt;br&gt;
at wrapSafe (node:internal/modules/cjs/loader:1055:15)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl7dlndjtubjyo2buwohf.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl7dlndjtubjyo2buwohf.jpg" alt=" " width="800" height="453"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The error appeared dozens of times and prevented the build from completing.&lt;/p&gt;




&lt;p&gt;Engineering Analysis&lt;/p&gt;

&lt;p&gt;This was not a logic error in the application code.&lt;/p&gt;

&lt;p&gt;Instead, it was an Interpreter Compatibility Conflict between the Node.js engine and the Windows environment.&lt;/p&gt;

&lt;p&gt;What was happening internally?&lt;/p&gt;

&lt;p&gt;• EAS Build calls internal Expo dependencies such as Metro configuration packages.&lt;br&gt;
• These packages rely on modern JavaScript syntax.&lt;br&gt;
• On Windows, Node.js failed to parse the "typeof" keyword inside the dependency source code.&lt;br&gt;
• Node interpreted it as an unexpected token, even though the syntax was valid.&lt;/p&gt;

&lt;p&gt;In short:&lt;/p&gt;

&lt;p&gt;«The build system failed before even reaching my application code.»&lt;/p&gt;




&lt;p&gt;Failed Troubleshooting Attempts&lt;/p&gt;

&lt;p&gt;I exhausted nearly every common solution used by developers on Windows environments:&lt;/p&gt;

&lt;p&gt;1️⃣ Removing Dependencies&lt;/p&gt;

&lt;p&gt;• Deleted "node_modules"&lt;br&gt;
• Deleted "package-lock.json"&lt;br&gt;
❌ Result: Failed&lt;br&gt;
Reason: The issue was not corrupted packages, but how the OS interpreted them.&lt;/p&gt;

&lt;p&gt;2️⃣ Changing Node.js Versions&lt;/p&gt;

&lt;p&gt;• Installed multiple LTS versions&lt;br&gt;
❌ Result: Failed&lt;br&gt;
Reason: The conflict originated from Windows shell environment variables and system-level parsing behavior.&lt;/p&gt;

&lt;p&gt;3️⃣ Clearing npm Cache&lt;/p&gt;

&lt;p&gt;npm cache clean --force&lt;/p&gt;

&lt;p&gt;❌ Result: Failed&lt;br&gt;
Reason: Temporary files were not responsible.&lt;/p&gt;

&lt;p&gt;4️⃣ Updating Build Tools&lt;/p&gt;

&lt;p&gt;• Updated EAS CLI&lt;br&gt;
• Updated Expo CLI&lt;br&gt;
❌ Result: Failed&lt;br&gt;
Reason: Tooling was healthy — the OS environment was not.&lt;/p&gt;

&lt;p&gt;5️⃣ Modifying Babel &amp;amp; App Configurations&lt;/p&gt;

&lt;p&gt;• Edited "babel.config.js"&lt;br&gt;
• Edited "app.json"&lt;br&gt;
❌ Result: Failed&lt;br&gt;
Reason: The error occurred before Babel was even invoked.&lt;/p&gt;




&lt;p&gt;The Turning Point — Migrating to Linux&lt;/p&gt;

&lt;p&gt;At this stage, Windows became a complete roadblock.&lt;/p&gt;

&lt;p&gt;Instead of wasting more time, I made a strategic engineering decision:&lt;/p&gt;

&lt;p&gt;«Move the entire development environment to a Unix-based system.»&lt;/p&gt;

&lt;p&gt;Steps Taken:&lt;/p&gt;

&lt;p&gt;✅ Installed VirtualBox&lt;br&gt;
✅ Created a virtual machine running Ubuntu Linux&lt;br&gt;
✅ Installed a fresh Node.js environment&lt;br&gt;
✅ Reinstalled Expo and EAS CLI&lt;br&gt;
✅ Cloned the same project files without modification&lt;/p&gt;




&lt;p&gt;The Critical Test&lt;/p&gt;

&lt;p&gt;Inside Linux, I ran the exact same command:&lt;/p&gt;

&lt;p&gt;eas build --platform android --profile production&lt;/p&gt;

&lt;p&gt;Result:&lt;/p&gt;

&lt;p&gt;✅ The error disappeared immediately&lt;br&gt;
✅ The build process started successfully&lt;br&gt;
✅ No code changes were required&lt;br&gt;
✅ No dependency changes were required&lt;/p&gt;

&lt;p&gt;The exact same project that failed on Windows worked flawlessly on Linux.&lt;/p&gt;




&lt;p&gt;Technical Explanation&lt;/p&gt;

&lt;p&gt;Linux systems are Unix-based, which aligns with the native environment used to design Node.js and Expo tooling.&lt;/p&gt;

&lt;p&gt;This provides:&lt;/p&gt;

&lt;p&gt;• Consistent file path handling&lt;br&gt;
• Stable environment variable management&lt;br&gt;
• Reliable JavaScript engine behavior&lt;br&gt;
• Better compatibility with modern build systems&lt;/p&gt;

&lt;p&gt;Meanwhile, Windows introduced hidden interpreter conflicts that disrupted dependency parsing.&lt;/p&gt;




&lt;p&gt;Key Lesson&lt;/p&gt;

&lt;p&gt;Sometimes the problem is not in:&lt;/p&gt;

&lt;p&gt;❌ Your code&lt;br&gt;
❌ Your libraries&lt;br&gt;
❌ Your build tools&lt;/p&gt;

&lt;p&gt;But in the execution environment itself.&lt;/p&gt;

&lt;p&gt;When facing persistent, unexplainable build errors:&lt;/p&gt;

&lt;p&gt;«Changing the operating system may be the most efficient solution.»&lt;/p&gt;




&lt;p&gt;الملخص&lt;/p&gt;

&lt;p&gt;واجهت خطأ غريب أثناء بناء نسخة الإنتاج لتطبيقي باستخدام Expo.&lt;br&gt;
التطبيق كان يعمل بشكل طبيعي في التطوير، لكن أثناء تنفيذ أمر بناء الأندرويد ظهر خطأ:&lt;/p&gt;

&lt;p&gt;SyntaxError: Unexpected token 'typeof'&lt;/p&gt;

&lt;p&gt;بعد تجربة جميع الحلول التقليدية على نظام Windows مثل حذف المكتبات وتحديث Node وتنظيف الكاش — استمرت المشكلة.&lt;/p&gt;

&lt;p&gt;اتضح أن السبب لم يكن في الكود، بل في تعارض بيئة Windows مع طريقة تفسير Node.js للمكتبات الحديثة.&lt;/p&gt;

&lt;p&gt;الحل كان بالانتقال إلى نظام Linux عبر جهاز وهمي Ubuntu.&lt;/p&gt;

&lt;p&gt;بمجرد تشغيل نفس المشروع ونفس أمر البناء على Linux:&lt;br&gt;
اختفى الخطأ فوراً ونجح البناء بدون أي تعديل.&lt;/p&gt;

&lt;p&gt;الدرس المهم:&lt;/p&gt;

&lt;p&gt;أحياناً بيئة التشغيل نفسها هي سبب المشكلة، وتغيير النظام قد يكون الحل الجذري.&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
