openclaw/patches/@mariozechner__clipboard@0.3.0.patch
spiceoogway c2904c14ab Fix clipboard module crash on linux-arm-gnueabihf (#4596)
Fixes #4596

The @mariozechner/clipboard dependency was missing native bindings for
32-bit ARM Linux (linux-arm-gnueabihf), causing OpenClaw to crash on
startup on platforms like Raspberry Pi 3 and earlier.

This patch makes the clipboard module gracefully handle missing native
bindings by:
- Emitting a warning instead of throwing a fatal error
- Providing stub implementations that throw informative errors when called
- Allowing OpenClaw to start and run normally (clipboard ops will fail
  if called, but the pi-coding-agent should still work)

The patch is applied via pnpm's patch mechanism, which allows us to
modify the clipboard module at install time without forking it.
2026-01-30 11:03:16 -05:00

95 lines
4.2 KiB
Diff

diff --git a/index.js b/index.js
index 020b8893194bc185ec9ad4f5fd0558f148aee4d5..5ebf0beb60cc043c71092bd39d50f9f17d31e5bc 100644
--- a/index.js
+++ b/index.js
@@ -288,30 +288,66 @@ switch (platform) {
throw new Error(`Unsupported OS: ${platform}, architecture: ${arch}`)
}
+// Provide stub implementations if native binding is not available
+// This allows the module to be required on unsupported platforms without crashing
if (!nativeBinding) {
- if (loadError) {
- throw loadError
+ const unsupportedPlatformError = new Error(
+ `Clipboard native bindings not available for ${platform}-${arch}. ` +
+ `Clipboard operations will not work. ` +
+ `Original error: ${loadError ? loadError.message : 'Unknown'}`
+ )
+
+ // Log warning but don't throw - allow the module to load
+ if (typeof process !== 'undefined' && process.emitWarning) {
+ process.emitWarning(unsupportedPlatformError.message, 'ClipboardUnsupportedPlatform')
+ } else {
+ console.warn('[clipboard]', unsupportedPlatformError.message)
+ }
+
+ // Provide stub implementations that throw informative errors when called
+ const notAvailable = (fnName) => {
+ return function() {
+ throw new Error(`Clipboard.${fnName} is not available on ${platform}-${arch}`)
+ }
}
- throw new Error(`Failed to load native binding`)
-}
-const { availableFormats, getText, setText, hasText, getImageBinary, getImageBase64, setImageBinary, setImageBase64, hasImage, getHtml, setHtml, hasHtml, getRtf, setRtf, hasRtf, clear, watch, callThreadsafeFunction } = nativeBinding
+ module.exports.availableFormats = notAvailable('availableFormats')
+ module.exports.getText = notAvailable('getText')
+ module.exports.setText = notAvailable('setText')
+ module.exports.hasText = notAvailable('hasText')
+ module.exports.getImageBinary = notAvailable('getImageBinary')
+ module.exports.getImageBase64 = notAvailable('getImageBase64')
+ module.exports.setImageBinary = notAvailable('setImageBinary')
+ module.exports.setImageBase64 = notAvailable('setImageBase64')
+ module.exports.hasImage = notAvailable('hasImage')
+ module.exports.getHtml = notAvailable('getHtml')
+ module.exports.setHtml = notAvailable('setHtml')
+ module.exports.hasHtml = notAvailable('hasHtml')
+ module.exports.getRtf = notAvailable('getRtf')
+ module.exports.setRtf = notAvailable('setRtf')
+ module.exports.hasRtf = notAvailable('hasRtf')
+ module.exports.clear = notAvailable('clear')
+ module.exports.watch = notAvailable('watch')
+ module.exports.callThreadsafeFunction = notAvailable('callThreadsafeFunction')
+} else {
+ const { availableFormats, getText, setText, hasText, getImageBinary, getImageBase64, setImageBinary, setImageBase64, hasImage, getHtml, setHtml, hasHtml, getRtf, setRtf, hasRtf, clear, watch, callThreadsafeFunction } = nativeBinding
-module.exports.availableFormats = availableFormats
-module.exports.getText = getText
-module.exports.setText = setText
-module.exports.hasText = hasText
-module.exports.getImageBinary = getImageBinary
-module.exports.getImageBase64 = getImageBase64
-module.exports.setImageBinary = setImageBinary
-module.exports.setImageBase64 = setImageBase64
-module.exports.hasImage = hasImage
-module.exports.getHtml = getHtml
-module.exports.setHtml = setHtml
-module.exports.hasHtml = hasHtml
-module.exports.getRtf = getRtf
-module.exports.setRtf = setRtf
-module.exports.hasRtf = hasRtf
-module.exports.clear = clear
-module.exports.watch = watch
-module.exports.callThreadsafeFunction = callThreadsafeFunction
+ module.exports.availableFormats = availableFormats
+ module.exports.getText = getText
+ module.exports.setText = setText
+ module.exports.hasText = hasText
+ module.exports.getImageBinary = getImageBinary
+ module.exports.getImageBase64 = getImageBase64
+ module.exports.setImageBinary = setImageBinary
+ module.exports.setImageBase64 = setImageBase64
+ module.exports.hasImage = hasImage
+ module.exports.getHtml = getHtml
+ module.exports.setHtml = setHtml
+ module.exports.hasHtml = hasHtml
+ module.exports.getRtf = getRtf
+ module.exports.setRtf = setRtf
+ module.exports.hasRtf = hasRtf
+ module.exports.clear = clear
+ module.exports.watch = watch
+ module.exports.callThreadsafeFunction = callThreadsafeFunction
+}