Skip to content

Comments

fix: datatype mismatch causes crash#4143

Merged
mfazekas merged 1 commit intornmapbox:mainfrom
g4rb4g3:bugfix/new-arch-datatypes
Feb 21, 2026
Merged

fix: datatype mismatch causes crash#4143
mfazekas merged 1 commit intornmapbox:mainfrom
g4rb4g3:bugfix/new-arch-datatypes

Conversation

@g4rb4g3
Copy link
Contributor

@g4rb4g3 g4rb4g3 commented Feb 3, 2026

Description

While switching to new architecture we spotted this issue:
image

Which this PR fixes. :)

@g4rb4g3 g4rb4g3 temporarily deployed to CI with Mapbox Tokens February 3, 2026 19:30 — with GitHub Actions Inactive
@g4rb4g3 g4rb4g3 temporarily deployed to CI with Mapbox Tokens February 3, 2026 19:30 — with GitHub Actions Inactive
@g4rb4g3 g4rb4g3 temporarily deployed to CI with Mapbox Tokens February 3, 2026 19:30 — with GitHub Actions Inactive
@mfazekas
Copy link
Contributor

Thanks much, Can you please add a demo component to reproduce the issue?!

@g4rb4g3
Copy link
Contributor Author

g4rb4g3 commented Feb 15, 2026

@mfazekas Sadly I'll not have a chance to do so in the the foreseeable future.
We use these methods on ABRP when running on CarPlay, currently we have added it as patch and it works flawless. No more Sentry logs on that topic. 🙂
As mentioned in the OP this started when we switched to new architecture. Since you are aiming for new arch only this will make sure it works just fine for everyone.

@mfazekas
Copy link
Contributor

Confirmed the issue and verified the fix. The crash happens because the TurboModule spec (NativeRNMBXCameraModule.ts) declares animationMode, animationDuration, and scaleFactor as number (→ double), but the Obj-C bridge and Swift receive them as NSNumber. On new architecture, the raw double bits get interpreted as an NSNumber pointer, crashing when .doubleValue is called.

Added a reproducer example to the example app:

Reproducer: Camera/MoveAndScale.tsx
import { useRef } from 'react';
import { View, StyleSheet, TouchableOpacity, Text } from 'react-native';
import { MapView, Camera, type CameraRef } from '@rnmapbox/maps';

const styles = StyleSheet.create({
  container: { flex: 1 },
  map: { flex: 1 },
  buttons: {
    position: 'absolute',
    bottom: 40,
    left: 20,
    right: 20,
    gap: 8,
  },
  button: {
    backgroundColor: 'rgba(255, 255, 255, 0.95)',
    padding: 14,
    borderRadius: 8,
    alignItems: 'center',
  },
  buttonText: { fontSize: 14, fontWeight: '600' },
});

const MoveAndScale = () => {
  const cameraRef = useRef<CameraRef>(null);

  return (
    <View style={styles.container}>
      <MapView style={styles.map}>
        <Camera
          ref={cameraRef}
          defaultSettings={{
            centerCoordinate: [-74.006, 40.7128],
            zoomLevel: 12,
          }}
        />
      </MapView>
      <View style={styles.buttons}>
        <TouchableOpacity
          style={styles.button}
          onPress={() => cameraRef.current?.moveBy({ x: 100, y: 0 })}
        >
          <Text style={styles.buttonText}>moveBy (no animation)</Text>
        </TouchableOpacity>
        <TouchableOpacity
          style={styles.button}
          onPress={() =>
            cameraRef.current?.moveBy({
              x: 0, y: -100,
              animationMode: 'easeTo',
              animationDuration: 500,
            })
          }
        >
          <Text style={styles.buttonText}>moveBy (animated 500ms)</Text>
        </TouchableOpacity>
        <TouchableOpacity
          style={styles.button}
          onPress={() =>
            cameraRef.current?.scaleBy({ x: 200, y: 400, scaleFactor: 2 })
          }
        >
          <Text style={styles.buttonText}>scaleBy 2x (no animation)</Text>
        </TouchableOpacity>
        <TouchableOpacity
          style={styles.button}
          onPress={() =>
            cameraRef.current?.scaleBy({
              x: 200, y: 400, scaleFactor: 0.5,
              animationMode: 'easeTo',
              animationDuration: 500,
            })
          }
        >
          <Text style={styles.buttonText}>scaleBy 0.5x (animated 500ms)</Text>
        </TouchableOpacity>
      </View>
    </View>
  );
};

export default MoveAndScale;

Crash occurs at let duration = (animationDuration?.doubleValue ?? 0.0) / 1000 in RNMBXCamera.swift when tapping any of the buttons (animated variants crash immediately, non-animated ones also crash since they hit the same line before the duration == 0.0 check).

Cherry-picked and verified the fix works — all 4 variants (moveBy/scaleBy with and without animation) work correctly after the change.

@mfazekas mfazekas merged commit 83641f4 into rnmapbox:main Feb 21, 2026
7 checks passed
@g4rb4g3
Copy link
Contributor Author

g4rb4g3 commented Feb 21, 2026

Thank you very much @mfazekas 🙂

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.

2 participants